License: CC BY 4.0

📕 READ ME

SUMMARY This R code estimates the relationship between oxygen consumption (MO₂) and dissolved oxygen saturation (DO) in the Common Galaxias (Galaxias maculatus). It also estimates the critical oxygen saturation value for aerobic metabolism O2crit, commonly defined as the threshold below which the oxygen consumption rate can no longer be sustained. The associated article is titled “The role of osmorespiratory compromise in metabolism and hypoxia tolerance of a purportedly oxyconforming teleost.” If you are reading the HTML version of this script, click the Code button in the top right to download the .Rmd file.

AIM The article aims to test whether Galaxias maculatus can maintain oxygen consumption (MO₂) as ambient DO declines and, if so, at what level it reaches the critical oxygen saturation value for aerobic metabolism (O2crit).

AUTHORS Timothy D. Clark [a] Luis L. Kuchenmüller [a] Elizabeth C. Hoots [a] Maryane Gradito [a] Jake M. Martin [a,b]

AFFILIATIONS [a] School of Life and Environmental Sciences, Deakin University, Geelong, VIC, Australia
[b] Department of Wildlife, Fish and Environmental Studies, Swedish University of Agricultural Sciences, Umeå, Sweden

DISCLAIMER I (Jake Martin) am dyslexic. I have made an effort to review the script for grammatical errors, but some will likely remain. I apologise. Please feel free to reach out using the contact details below if anything is unclear.

📧 Contact

Jake M. Martin

📧 Email: jake.martin@deakin.edu.au

📧 Alt Email: jake.martin.research@gmail.com

🌐 Web: jakemartin.org

🐙 GitHub: JakeMartinResearch

📑 Sharing/accessing and citing

  1. Licenses/restrictions placed on the data: CC-BY 4.0

  2. Link to the associated publication:
    🚧 To be added 🚧

  3. Recommended citation for this data:

Clark, T. D., Kuchenmüller, L. L., Hoots, E. C., Gradito, M., & Martin, J. M. (2025, May 28). The role of osmorespiratory compromise in hypoxia tolerance of the purportedly oxyconforming teleost Galaxias maculatus. https://doi.org/10.17605/OSF.IO/GFXCA

📦 Required packages and knit settings

A list of the required packages to run the script.

# ----- Packages ------
if (!requireNamespace("pacman", quietly = TRUE)) install.packages("pacman")

# ---- List of required packages ----
pkgs <- c(
  # ----- Data Visualisation -----
  "ggthemes", "bayesplot", "gt", "gtsummary", "plotly", "qqplotr", "gridExtra",
  
  # ----- Tidy Data and Wrangling -----
  "tidyverse", "janitor", "readxl", "broom.mixed", "data.table", "hms", "devtools",
  "mclust",
  
  # ----- Modelling and Statistical Analysis -----
  "brms", "rstan", "marginaleffects", "performance", "emmeans",
  "tidybayes", "respirometry", "future"
)

# ---- Install and load all packages using pacman ----
suppressPackageStartupMessages(
  pacman::p_load(char = pkgs, install = TRUE)
)

#-------kniter seetting-----------

knitr::opts_chunk$set(
  echo = FALSE, # only for PDF knit
  message = FALSE,
  warning = FALSE, # no warnings
  cache = TRUE,# cacheing to save time when kniting
  tidy = TRUE,
  fig.align = "center" 
)

🔧 Custom functions

Here are some custom functions used within this script.

bayes_incremental_regression_by_id(): A custom function to build Bayesian incremental regressions. It is designed to run a list of subgroup models (IDs) in parallel using 4 cores. The function uses brm() with a Gaussian error distribution.

Use:
The function accepts the following arguments:
- id_i: A grouping factor or ID used to filter the data for each regression. If none is provided, the function uses the entire dataset.
- id_name: The column name (as a character string) corresponding to the grouping factor in the data frame. If not provided, the function uses all data.
- data: The data frame containing the variables for analysis.
- predictor: The predictor variable of interest.
- response: The response variable of interest.
- seed_number: A random seed value for model reproducibility.
- save_models: A logical argument indicating whether to save the model outputs (TRUE or FALSE).
- mod_output_wd: The output directory where model .rds files should be saved (used only if save_models = TRUE).

load_rds9(): A custom function to load all rds models in a directory and store in a list. Takes a directory with .rds files

incremental_regression_bayes_fits(): A custom function for pulling model fits, loo and r2 using loo() and bayes_R2(), respectively. Takes a list of brm models.

bayes_mod_predictions(): This function extracts the predicted values using fitted() from a list of models and combines them with the original data file used for the model. These are the posterior mean fitted values (i.e. the expected value of the response variable given the predictor variables and the estimated posterior distributions of the parameters) for each observation in the dataset, along with 95% credible intervals.

calcSMR(): authored by Denis Chabot used to estimate SMR with several different methods Claireaux and Chabot (2016) [1]

[1] Claireaux, G. and Chabot, D. (2016) Responses by fishes to environmental hypoxia: integration through Fry’s concept of aerobic metabolic scope. Journal of Fish Biology https://doi.org/10.1111/jfb.12833

calcO2crit(): authored by Denis Chabot used to estimate O2crit (Pcript). Claireaux and Chabot (2016) [1]

Note: O2 is assumed to be in percentage of dissolved oxygen (DO)

plotO2crit(): authored by Denis Chabot, used to plot the modes used for the calcO2crit() function. Claireaux and Chabot (2016) [1]

Note: I added abline(h=lowestMO2, col=“pink”) so that I could visualise the lowestMO2 position

📂 Directories

Input

📥 input_data_wd: Directory for the metadata

📥 mod_data_wd: Directory for model output data estimated slopes

Output

📤 output_fig_wd: this is where we will put the figures

📤 output_mods_wd: this is where we will put the models

💿 Data

Slopes (ṀO)

💿 slope_df: We have imported the slopes extracted in LabChart during each phase of the experiment

Fish metadata

💿 metadata: This is the meta data for each chamber

Note: We are also adding volume based on chamber type.

Urbina, Glover, and Forster (2012)

💿 urbina_et_al_2012: This is the mean level data extracted from Urbina, Glover, and Forster (2012)[2] Figure 1a. We used the metaDigitise package in R to extract the data [3].

O₂crit viusal inspection

💿 o2crit_check: This data frame includes the visual based assessment for O₂crit for all fish included in the analysis (n = 58). The inspections were made using figures genbrated by the plotO2crit() function, and can be viewed in combined_chabot_plots.pdf. The visual assessment was done independently by all authors, and the presence of an O₂crits allocated to ‘yes’, ‘no’, ‘maybe’. If yes, or maybe, an estimate of the dissolved oxygen percentage was given.

Directory to the figures

📁 gmac-mo2-24/ └── 📂 output-fig/
└── 📂 model_chabot/ └── 📄 combined_chabot_plots.pdf

Combinding metadata

Adding the meta data to the slopes data frame

🧹 Data tidy

Numbers

We have 64 fish with MO₂ data

## [1] "n = 64"

With 48 from the 0 ppt and 48 from 9 ppt groups

Salinity group n total
0 33
9 31

Fish size

Here we calculate the mean length and size of fish used in the experiment.

## [1] "The mean mass of fish was 0.532 g (range: 0.21-1.6), and the mean length was 50.41 mm (range: 40-70)"

Filtering trials

We will remove 6 trials which had errors. These are as follows:

  • a_0_25nov_3 fish died during trial
  • b_0_26nov_4 flat lined early
  • c_0_22nov_2 chamber was opened early
  • c_9_26nov_2 chamber was opened early
  • c_9_26nov_4 chamber was opened early
  • d_9_27nov_3 sensor was jumpy and end points were hard to confidently ID visually

We now have 58 fish with MO2 data

## [1] "n = 58"

With 30 in the 0 ppt group and 28 in the 9 ppt group

Salinity group n total
0 30
9 28

Mass and size of fish after removing 6 trials which had errors

## [1] "The mean mass of fish was 0.546 g (range: 0.21-1.6), and the mean length was 50.9 mm (range: 40-70)"

Chamber size breakdown

Chamber type n total Median mass Standard deviation mass
0.058 36 0.43 0.1496554
0.105 21 0.61 0.2561871
0.300 1 1.60 0.0000000

Numbers per trial approach

Type of trial n total
100c 19
50c 39

Filtering MO₂ estimates

Here we apply the following filters to the MO₂ data:

  • Remove the first 5 SMR cycles (burn in)
  • Remove all positive raw slopes
  • Remove all MO₂ calculated using less then 60 data points (5 min at 0.2 Hz)
  • Remove all MO₂ calculated if O₂ increases in a closed phase (i.e. trial has ended)

Check positive values for MO₂ before removing.

## [1] "There are 13 fish with postive slopes. These fish are: a_0_24nov_1, b_0_24nov_3, b_9_21nov_2, b_9_21nov_3, b_9_22nov_1, b_9_22nov_2, b_9_22nov_3, c_0_21nov_1, c_0_21nov_2, c_0_22nov_4, c_9_24nov_3, d_0_22nov_2, d_9_25nov_3. For all estimated slopes (n = 1105) 1.27% were postive (n = 14)"

Filtering the MO₂ data

Calculating SMR

We will calculate SMR using calcSMR function by Chabot, Steffensen and Farrell (2016)[1]. Specifically, we use mean of the lowest normal distribution (MLND) where CVmlnd < 5.4 and the mean of the lower 20% quantile (q0.2) were CVmlnd > 5.4. If CVmlnd is not calculated we have used q0.2.

Transforming MO₂

Here we are transforming the MO₂ units. The resulting values are as follows:

  • MO2 is absolute value of the background and leak corrected MO₂ slope from Labchart (mo2corr) times the net volume of the chamber (volume - fish mass), × 60, × 60, to achieve MO₂ as mg-1 O₂ h-1

  • MO2_g is MO2 divided by fish mass to achieve MO₂ as mg-1 O₂ g-1 h-1 (i.e. mass standardised)

  • SMR absolute value of the SMR estimates using methods described by Chabot, Steffensen and Farrell (2016)[1] times the net volume of the chamber (volume - fish mass), × 60, × 60, to achieve SMR as mg-1 O₂ h-1)

  • SMR_g is SMR divided by fish mass to achieve SMR as mg-1 O₂ g-1 h-1 (i.e. mass standardised)

  • DO is dissolved oxygen percentage calculated from O₂ values (mg-1 L-1) using the recorded temperature, salinity, and a constant atmospheric pressure (Pa; 1013.25)

  • o2_kpa is the O₂ concentration in kilopascal (kpa). This is used to make a comparative figure only.

Trial lengths

Approach Minimum duration Maximum duration Median duration
Closed at 100% air saturation 3 13 7
Closed at 75% and 50% air saturation 2.91 8.02 5.96

Visualising MO2 corrections

Let’s check how data corrections change the appearance of out data MO2

Let’s compare raw MO2 calculations (mo2), MO2 calculations after correcting background respiration (mo2_bground), and MO2 calculations after correcting for background respiration and oxygen diffusion dynamics (mo2corr). First we will need to make the mo2_bground vaule as it’s not present in the datafile, and transform the data to long formate, so we can plot it more easly.

Figure S1

Now let’s plot them in the same graph for each fish: raw MO₂ calculations are shown in pink, MO₂ calculations after correcting for background respiration are shown in grey, and MO₂ calculations after correcting for background respiration and oxygen diffusion dynamics are shown in green.

Figure S1: Individual fish-level plots showing the relationship between dissolved oxygen (DO) percentage and metabolic oxygen consumption rate (MO₂, in mg O₂/g/h) for each 20-min interval. Each panel displays data for a single fish (fish ID in the top left of the plot). Points are colour-coded by the type of MO₂ calculation: raw MO₂ (pink, #f692B4), background-corrected MO₂ (grey, #6E7889), and fully corrected MO₂ (accounting for background respiration and oxygen diffusion dynamics) (green, #53af8b). Each point represents a measurement at a specific DO level, and the slight transparency (alpha = 0.5) highlights overlapping observations.

📊 Exploratory Data Analysis (EDA)

O₂ vs MO₂

Figure S2

This interactive was used to identify any outliers, or potential errors. This has not been generated in the PDF Supplementary file 1, as it is not compatible.

Figure S2: interactive plot of metabolic rate measurements (MO₂; mg O₂ g-1h-1) by dissolved oxygen percentage (DO) for all fish, including all estimates during the SMR phase (i.e. intermittent phase). Individual linear regression were fitted for visual reference, and do not represent the best fitting regression.

Figure S3

Looking at the difference responses in the two salinity groups.

Figure S3: Metabolic rate measurements (MO₂; mg O₂ g-1h-1) by dissolved oxygen percentage (DO) for fish from the two salinity treatments, including all estimates during the SMR phase (i.e. intermittent phase). Individual linear regression were fitted for visual reference, and do not represent the best fitting regression. The solid red and dashed red line represents the global trend in each of the treatments, both a linear (solid red) and non-linear (dashed red; Generalized Additive Model fitted with geom_smooth).

Figure S4

A plot to look at the different chamber types

Figure S4: Metabolic rate measurements (MO₂; mg O₂ g-1h-1) by dissolved oxygen percentage (DO) for fish tested in the 4 different chamber types, including all estimates during the SMR phase (i.e. intermittent phase). Individual linear regression were fitted for visual reference, and do not represent the best fitting regression. The solid red and dashed red line represents the global trend in each of the treatments, both a linear (solid red) and non-linear (dashed red; Generalized Additive Model fitted with geom_smooth).

Routine MO₂

Making an SMR phase only data frame

Routine MO2 by salinity. Plot of all MO2 measures during SMR phase by salinity treatment. The small points are the raw observed values, the shaded area behind the points is the a kernel density of the observed data, the box plot shows the median and interquartile range (IQR), and the large point shows the mean.

SMR

Here’s the same plot but for only the SMR, as estimated with calcSMR function by Chabot, Steffensen and Farrell (2016)[1]. Specifically, we use mean of the lowest normal distribution (MLND) where CVmlnd < 5.4 and the mean of the lower 20% quantile (q0.2) were CVmlnd > 5.4. If CVmlnd is not calculated we have used q0.2.

Individual O₂, MO₂, and SMR

Here we will plot the individual relationship between O₂, MO₂, and SMR for all fish

Create output directory if needed

Loop through each fish ID to create a plot, save these to a single PDF file, this is called combined_slopes.pdf. It can be found in this path output-fig/slopes/combined_slopes.pdf These plots show Metabolic rate measurements (MO₂; mg O₂ g-1h-1 by O2) at each of the four experimental phase (the over night SMR intermittent-flow respirometry phase, closed phases at 50%, 75% or 100% O2). The estimated SMR value is represented as a dashed red line.

## png 
##   2

🧮 Analysis

Routine MO2

Scaling predictors

Here we scale our predictors for the model. We have first applied an log transformation to mass, so its directly interpretable as the mass-scaling exponent, just like in metabolic theory.

Summary of predictors used in the model below

temp_range mass_range cycle_range number_fish
13.84–14.38 0.21–1.6 5–27 58

Model structure

Here we will use a Bayesian Generalised Linear Mixed Model (GLMM) with a Gamma distribution and a log link, where the shape parameter (α) is also modelled as a function of predictors. This models MO2 by salinity during the SMR phase to see if the fish held at different salinities have different RMRs. We have also added a few scaled predictors, that may help describe variation in the data, such as mass (g; 0.21–1.6) temperature (°C; 13.84–14.38), cycle order (5–27), and light/dark cycle (light or dark; light between 07:00:00 and 19:00:00), we also include a random effect for fish id to account for multiple MO2 measures on each fish (1–58). We allowed the the shape parameter (α) to vary as a function of some of the predictors (e.g. salinity_group, order_z) to improve fit.

Prior selection

These are the default priors. We will use these.

prior class coef group resp dpar nlpar lb ub source
b default
b light_dark_c default
b log_mass_c default
b order_c default
b salinity_group9 default
b temp_c default
student_t(3, -2.7, 2.5) Intercept default
student_t(3, 0, 2.5) sd 0 default
sd id default
sd Intercept id default
b shape default
b order_c shape default
b salinity_group9 shape default
student_t(3, 0, 2.5) Intercept shape default

Run model

Here we run the model, I have hashed this out because I have saved the model for quick reloading.

⏭️ Skip this step if you have downloaded the saved model mo2_mod_gamma.rds from GitHub (or pulled the entire GitHub project)

Here we reload the model

Model diagnostics

Checking model convergence

Checking rhat are equal to one

##  Family: gamma 
##   Links: mu = log; shape = log 
## Formula: MO2 ~ temp_c + order_c + light_dark_c + log_mass_c + salinity_group + (1 | id) 
##          shape ~ salinity_group + order_c
##    Data: slope_tidy_smr (Number of observations: 893) 
##   Draws: 4 chains, each with iter = 8000; warmup = 1000; thin = 2;
##          total post-warmup draws = 14000
## 
## Multilevel Hyperparameters:
## ~id (Number of levels: 58) 
##               Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## sd(Intercept)     0.31      0.03     0.26     0.38 1.00     4013     6644
## 
## Regression Coefficients:
##                       Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS
## Intercept                -2.54      0.06    -2.66    -2.43 1.00     2241
## shape_Intercept           2.58      0.07     2.45     2.72 1.00    12143
## temp_c                   -0.33      0.21    -0.75     0.09 1.00     6431
## order_c                   0.00      0.00    -0.00     0.01 1.00    11445
## light_dark_c              0.13      0.02     0.09     0.18 1.00    12311
## log_mass_c                0.81      0.10     0.61     1.01 1.00     2943
## salinity_group9          -0.10      0.08    -0.26     0.07 1.00     2304
## shape_salinity_group9     0.18      0.10    -0.03     0.37 1.00    12404
## shape_order_c            -0.04      0.01    -0.06    -0.02 1.00    11624
##                       Tail_ESS
## Intercept                 4183
## shape_Intercept          12331
## temp_c                    9409
## order_c                  12155
## light_dark_c             12266
## log_mass_c                5032
## salinity_group9           4394
## shape_salinity_group9    12389
## shape_order_c            12394
## 
## Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
## and Tail_ESS are effective sample size measures, and Rhat is the potential
## scale reduction factor on split chains (at convergence, Rhat = 1).

Using leave one out (loo) measure of fit, the model appears to preform well, all, but one Pareto k estimates are good (k < 0.7)

## 
## Computed from 14000 by 893 log-likelihood matrix.
## 
##          Estimate   SE
## elpd_loo   2256.8 38.9
## p_loo        71.6  7.1
## looic     -4513.5 77.8
## ------
## MCSE of elpd_loo is NA.
## MCSE and ESS estimates assume MCMC draws (r_eff in [0.7, 1.0]).
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. ESS
## (-Inf, 0.7]   (good)     892   99.9%   765     
##    (0.7, 1]   (bad)        1    0.1%   <NA>    
##    (1, Inf)   (very bad)   0    0.0%   <NA>    
## See help('pareto-k-diagnostic') for details.

Model predictions generally align with the observed data

📈 Results

We did not see a meaningful difference between the routine metabolic rate for fish from the two salinity treatments.

Table S1

Table S1: Fixed effect Estimates (β) and 95% Credible Intervals (95% CI)

Predictor β 95% CI
Intercept -2.545 [-2.659, -2.428]
shape_Intercept 2.585 [2.45, 2.715]
temp_c -0.335 [-0.755, 0.087]
order_c 0.002 [-0.002, 0.005]
light_dark_c 0.134 [0.086, 0.182]
log_mass_c 0.805 [0.609, 1.006]
salinity_group9 -0.096 [-0.259, 0.066]
shape_salinity_group9 0.177 [-0.025, 0.372]
shape_order_c -0.041 [-0.059, -0.023]

Looking at the marginal mean MO2 for each salinity treatment

salinity_group emmean lower.HPD upper.HPD
0 0.079 0.070 0.088
9 0.071 0.064 0.080

These are the estimated mean constrast, we have exponentiated the log estimate to get the fold-change. This means the model predicts that sailianty group 0 has ~12% higher metabolic rate than group 9 (1.12)—but this difference is not credible, because the interval for that difference includes no difference (i.e. a ratio of 1.0).

contrast estimate lower.HPD upper.HPD
salinity_group0 - salinity_group9 1.1 0.94 1.29

EEM contrasts for the two light phases, where -0.5 is dark, and 0.5 is light

contrast estimate lower.HPD upper.HPD
light_dark_c0.5 - (light_dark_c-0.5) 1.14 1.09 1.2

Here we we calculate the model-estimated marginal means for MO2 for a unit increase in mass and transform this onto a fold-change scale. Where log(mass) has be centered, a vaule of 0 represents the mean mass of fish, and 1 corresponds to a fish with log(mass) = 1 unit above the mean (i.e. 2.7 times large).

log(mass2) = log(mass1)+1

If you exponentiate both sides:

mass2 = mass1 x exp(1)

mass2 ≈ mass1 x 2.718

contrast estimate lower.HPD upper.HPD
log_mass_c1 - log_mass_c0 2.23 1.86 2.76

Pulling the emmeans draws for our plot

Figure 1a

NOTE: This plot is in the main text of the manuscript, which is way it is called Figure 1a (not Figure Si)

Figure 1a: Routine metabolic rate (i.e. MO2 (mg-1 O2 h-1) measured during SMR meassurments) plotted by salinity treatment. The small transparent points are the observed values, the shaded area behind the points is the a kernel density of the observed data, the large coloured point (to the right) is the observed mean, the large grey point with error bars (to the left) is the model estimated marginal mean (eemean) 95% Credible Intervals (95% CI).

There was moderate but meaningful variation in RMR between individuals, even after accounting for mass, temperature, salinity, and light phase. The estimated standard deviation of individual RMR was 0.31 [0.26 to 0.38], indicating that individual identity explained a meaningful proportion of the observed variation.

Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
0.3109591 0.0317821 0.2555882 0.3785216 1.000639 4013.05 6644.265

SMR

Formating and scaling data

Here we are filtering the data frame to have only measure per fish for the SMR estimate

Summary of predictors used in the model below

temp_range mass_range cycle_range number_fish
13.87–14.26 0.21–1.6 10–23 58

Model structure

Here we will use a Bayesian Generalised Linear Mixed Model (GLMM) with a Gamma distribution and a log link Gamma(link = "log"), where the shape parameter (α) is also modelled as a function of the salinity group, shape ~ salinity_group. This models MO2 by salinity during the SMR phase to see if the fish held at different salinities have different SMRs. We have also added a few scaled predictors, that may help describe variation in the data, such as fish mass (g; 0.21–1.6) mean temperature (°C; 13.841–14.277), and the number of cycles over which SMR was estimated (1–23). We allowed the the shape parameter (α) to vary as a function of salinity_group to improve fit.

Prior selection

These are the default priors for the model. We will use these.

prior class coef group resp dpar nlpar lb ub source
b default
b cycles_c default
b log_mass_c default
b salinity_group9 default
b temp_mean_c default
student_t(3, -2.8, 2.5) Intercept default
b shape default
b salinity_group9 shape default
student_t(3, 0, 2.5) Intercept shape default

Run model

Here we run the model, I have hashed this out because I have saved the model for quick reloading.

⏭️ Skip this step if you have downloaded the saved model ‘smr_mod_gamma.rds’

Here we reload the model

Model diagnostics

Checking model convergence

Using leave one out (loo) measure of fit, the model appears to preform well, two Pareto k estimates falls outside the good range (0.7, 1]

## 
## Computed from 14000 by 58 log-likelihood matrix.
## 
##          Estimate   SE
## elpd_loo    134.6 11.0
## p_loo        11.0  4.8
## looic      -269.2 22.0
## ------
## MCSE of elpd_loo is NA.
## MCSE and ESS estimates assume MCMC draws (r_eff in [0.8, 0.9]).
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. ESS
## (-Inf, 0.7]   (good)     56    96.6%   4028    
##    (0.7, 1]   (bad)       1     1.7%   <NA>    
##    (1, Inf)   (very bad)  1     1.7%   <NA>    
## See help('pareto-k-diagnostic') for details.

Model predictions generally align with the observed data, but there is a lot of uncertainty around this estimate.

📈 Results

We did not see a meaningful difference between the routine metabolic rate for fish from the two salinity treatments.

Table S2

Table S2: Fixed effect Estimates (β) and 95% Credible Intervals (95% CI) from a Bayesian Generalised Linear Mixed Model (GLMM) with a Gamma distribution and a log link

Predictor β 95% CI
Intercept -2.740 [-2.879, -2.603]
shape_Intercept 2.010 [1.428, 2.532]
temp_mean_c -0.364 [-1.51, 0.802]
cycles_c -0.005 [-0.026, 0.018]
log_mass_c 0.816 [0.597, 1.034]
salinity_group9 -0.086 [-0.283, 0.111]
shape_salinity_group9 0.117 [-0.733, 0.945]

Looking at the marginal mean difference between salinity groups

salinity_group emmean lower.HPD upper.HPD
0 0.065 0.056 0.074
9 0.059 0.052 0.067
contrast estimate lower.HPD upper.HPD
salinity_group0 - salinity_group9 1.09 0.89 1.32

Here we we calculate the model-estimated marginal means for SMR for a unit increase in mass and transform this onto a fold-change scale. Where log(mass) has be centered, a vaule of 0 represents the mean mass of fish, and 1 corresponds to a fish with log(mass) = 1 unit above the mean (i.e. 2.7 times large).

contrast estimate lower.HPD upper.HPD
log_mass_c1 - log_mass_c0 2.26 1.84 2.84

Pulling the emmeans draws for our plot

Figure 1b

NOTE: This plot is in the main text of the manuscript which is why it is Figure 1b (not Figure Si)

Figure 1b: The standard metabolic rate estimate (mg-1 O2 h-1) plotted by salinity treatment. The small transparent points are the observed values, the shaded area behind the points is the a kernel density of the observed data, the large coloured point (to the right) is the observed mean, the large grey point with error bars (to the left) is the model estimated marginal mean (eemean) 95% Credible Intervals (95% CI).

Incremental regression analyses

Here we are following the methods Urbina et al. (2012)[1] with an incremental regression analyses, in order to determine the best fit for the MO2 vs O2 data

This analysis approach evaluates the relative ‘fit’ of each polynomial order equation starting at zero and increasing to the third order, permitting a mathematical assessment of whether fish were oxyconforming or oxyregulatoring. If the data is best fitted/predicted by a single linear relationship (1st-order polynomial) with a positive slope, this would suggests the fish were oxyconforming. Alternately, if the relationship is best modelled by a flat regression (0th-order polynomial), or a higher order polynomial (2nd or 3rd-order polynomial) the fish is likely oxyregulatoring.

Building Bayesian regressions

Here we are using a Bayesian approach to model fitting with brm. These models take a long time to run, so I have saved them and re-loaded them to save time. I have also saved the summary data produced from the models, to save time, you can simply skip the hashed code and input the resulting summary data.

We will run our custom function, bayes_incremental_regression_by_id.

Let’s make define the output directory

⏭️ Skip this step if you have already run this once, or have downloaded the saved models or saved data files from GitHub (that’s why its hashed out). ⌛This code takes a while to run

During this part of the script I received an error, ‘Caused by error in socketConnection():’. I think the system may be hitting a limit on the number of simultaneous socket connections. If you this part of the code and also get this issue, try reducing the number of parallel workers: plan(multisession, workers = 2), or run again after the error.

Load all models and store in a list, will use a lot of memory. You can also skip this step and load the resulting data frames below. I am using the custom function load_rds, so we can compare them and generate predictions.

⏭️ Skip this step if you have downloaded the saved data pulled from these models have also hased this out, bayes_reg_mods_fit.csv’ and ‘bayes_reg_mods_predictions.csv’. These are in the mod-data directory.

Model fits

⏭️ Skip this step if you have downloaded 💿 bayes_reg_mods_fit.csv.

It gets model fit parameters loo and r2 using the custom function, incremental_regression_bayes_fits. ⌛ This code takes a while to run ⌛

Reading in this model fit data frame, in the case you did not load in all the models.

Selecting the best fitting model

elpd_loo, or the expected log pointwise predictive density for leave-one-out cross-validation, is a metric used in Bayesian model evaluation to assess the predictive accuracy of a model. The elpd_loo is an approximation of how well the model is expected to predict new data, based on leave-one-out cross-validation. Higher elpd_loo values indicate better predictive performance.

Model predictions

⏭️ Skip this step if you have downloaded 💿 bayes_reg_mods_predictions.csv.

It pulls our model predictions using a custom function bayes_mod_predictions.

Reading in the predicted data

We are going to combined this with our best fitting model df, so we know how they ranks for LOO.

📈 Results

Model selection summary

In most cases, the relationship between MO2 and DO was best modelled with a 2nd-order polynomial (n = 22, 38% of fish), followed by a 3rd-order polynomial (n = 15, 26%), 1st-order polynomial (n = 11, 19%), and finally 0th-order polynomial (n = 10, 17%).

For the two most common models, 2nd- and 3rd-order polynomials, this could suggest the presence of a critical oxygen threshold (Pcrit) where the relationship between MO2 and O2 changes. To confirm the presence of a Pcrit, we need to validated the shape of the polynomials (see Pcrit model below). In any case, these type of models are indicative of oxyregulator.

The next most common model was is 1st-order polynomial. In the case of the 1st-order polynomials, it suggest the presences of linear relationship between o2 and MO2, which is indicative of oxyconformer. However, to be true evidence of a oxyconformer this relationship should be positive (i.e. as O2 falls MO2 also falls). 13 of the 18 individuals best modelled with a linear function had positive estimates with credible intervals that did not overlap with zero (Table S3).

Lastly, 0th-order was the least common (n = 3, 5%), it suggests that MO2 does not show a statistically significant dependence on the O2. In other words, the metabolic rate does not adjust based on oxygen availability, and there is no clear critical oxygen threshold (Pcrit) where the relationship changes. This is indicative of a oxyregulator.

best_model_name n percent
0th-order polynomial 10 17.24
1st-order polynomial 11 18.97
2nd-order polynomial 22 37.93
3rd-order polynomial 15 25.86

Summary of fish best model with a linear function.

Table S3

Table S3: Ten fish that were best modelled with a linear function, showing r2, and estimate (). Only two fish had positive estimates with credible intervals that did not overlap with zero, which are highlighted as conforming in the table. Thus in total, 13 of 58 fish showed sufficient evidence to be conforming.

Fish ID r2 (CI) Estimate (CI) Percentage change Evidence of oxyconforming
d_9_25nov_3 0.197 (0.012 to 0.394) 0.0011 ( 0.0003 to 0.0019) 0.7437151 Conforming
a_9_22nov_4 0.312 (0.094 to 0.491) 0.0008 ( 0.0004 to 0.0013) 0.5739880 Conforming
b_9_22nov_1 0.231 (0.055 to 0.396) 0.0005 ( 0.0002 to 0.0008) 0.4310066 Conforming
d_9_25nov_2 0.330 (0.102 to 0.507) -0.0009 (-0.0013 to -0.0004) -0.7599381 Not conforming
a_0_25nov_1 0.137 (0.002 to 0.331) -0.0004 (-0.0007 to 0.0000) -0.2788575 Not conforming
c_0_22nov_3 0.072 (0.000 to 0.256) 0.0005 (-0.0005 to 0.0016) 0.3013443 Not conforming
a_0_24nov_3 0.058 (0.000 to 0.202) 0.0005 (-0.0003 to 0.0012) 0.2832654 Not conforming
c_9_27nov_2 0.068 (0.000 to 0.255) 0.0003 (-0.0003 to 0.0008) 0.1697994 Not conforming
a_9_22nov_1 0.084 (0.000 to 0.266) 0.0003 (-0.0002 to 0.0008) 0.2272965 Not conforming
b_0_25nov_2 0.108 (0.001 to 0.290) 0.0003 ( 0.0000 to 0.0006) 0.2275231 Not conforming
a_0_24nov_1 0.029 (0.000 to 0.134) 0.0002 (-0.0005 to 0.0009) 0.1072286 Not conforming

Ploting all models

Data set with all slopes and which model was best

Saving all regression, and highlighting the model that has the best fit, based on AIC values. This is called combined_reg_plots.pdf

Getting a plot for each best fit regression, and overlaying a global model for that model type.

Here we are grouping fish by best fitting model and getting an average trend. I have hashed the code so you don’t need to re-run the models

⏭️ Skip this step if you have downloaded the global models ‘.rds’ in the ‘bayes-regs-global’ folder

⏭️ Skip this step if you have downloaded the global_models_pred_df.csv

Load data frame

Figure S5

Best fit regressions with global models based on that polynomial order.

Figure S5: Individual regression curves showing the relationship between mass-specific oxygen consumption rate (ṀO₂; mg⁻¹ O₂ h⁻¹) and ambient dissolved oxygen (DO; % saturation), grouped by the best-fitting polynomial order (0ᵗʰ to 3ʳᵈ). Each panel represents fish whose ṀO₂–DO relationship was best modelled by that polynomial order, based on leave-one-out cross-validation (LOO-CV). Grey lines represent individual model fits; the bold pink line shows the group-level trend within each polynomial class. Fish were most commonly best fit by a 2ⁿᵈ-order polynomial (n = 22), followed by 3ʳᵈ-order (n = 15), 1ˢᵗ-order (n = 11), and 0ᵗʰ-order (**n = 10). Higher-order fits (2ⁿᵈ and 3ʳᵈ) and 0ᵗʰ-order fits are generally indicative of oxyregulating responses, while 1ˢᵗ-order fits may suggest oxyconforming behaviour when positively sloped.

O₂crit model

We will calculate O₂crit using Chabot method and function calcO2crit.

This function uses the fifth percentile of the MO2 values observed at dissolved oxygen levels ≥ 80% air saturation as the criterion to assess low MO2 values. The algorithm then identifies all the MO2 measurements greater than this minimally acceptable MO2 value. Within this sub-set, it identifies the MO22 measurement made at the lowest DO and thereafter considers this DO as candidate for breakpoint (named pivotDO in the script). A regression is then calculated using observations at DO levels < pivotDO, and a first estimate of O2crit is calculated as the intersection of this regression line with the horizontal line representing SMR. The script then goes through validation steps to ensure that the slope of the regression is not so low that the line, projected to normoxic DO levels, passes below any MO2 values observed in normoxia. It also ensures that the intercept is not greater than zero. Corrective measures are taken if such problems are encountered.

lowestMO2 default is the quantile(MO2[DO >= 80], p=0.05). It is used to segment the data and locate the pivotDO.

Ploting O2crit

Here’s we are saving all O2crit models, even those MO2-O2 relationships best modelled by 0th- and 1st-order polynomials.

## png 
##   2

Now printing the fish that were fitted with higher order-polynomials in the htlm document

O₂crit numerical rules

We applied a numerical rule to asses if a O2crit was observed. Specifically, we filtered for only cases were at the lowest O₂ value three consecutive MO₂ measures full below our SMR and fifth percentile of the MO2 values observed at dissolved O2 levels > 80%. In the model output these are called nb_mo2_conforming points.

## [1] "Based on this rule there are 16 fish with possible O₂crits."

Figure S6

Plotting fish that meet our numerical rule for O2crit

Figure S6: Representative examples of fish that were best modelled by a 2nd- or 3rd-order polynomial and meet the numerical inclusion criteria. The horizontal solid orange line shows the standard metabolic rate (SMR), the horizontal solid pink line shows thelowestMO2 (as defined by Claireaux and Chabot (2016)), the solid/dashed blue/green slope line shows the O2 regulation failure regression (based on the rule-based linear regression method of Claireaux and Chabot (2016); where the colour and line type indicate the type of regression fitted, through orgin or not), and the solid vertical blue/green line shows the O2crit estimate (intersection of O2 failure regression and SMR).

How many from each salinity treatment

salinity_group n
0 9
9 7

Visual inspection

We conducted visual inspection of all 58 fish to determine if O2crits were present. We have loaded this as a data frame 💿 o2crit_check

For this visual inspection, we grouped fish into “no”, “maybe” or “yes”, based on the certainty at which we observed a O2crits. In the case of yes or maybe, we also estimate dissolved oxygen percentage. All authors did this independently.

📈 Results

Let’s figure out how consistent the categorisation was, and what the majority response was. There were 35 cases with no disagreements (60.34%), 23 cases with one or more disagreements (39.66%).

cat_disagreement n percent
0 35 60.34
1 23 39.66

Figure S7

Here’s a heat map to show decisions for each fish

Figure S7: Heatmap showing the visual assessment of critical oxygen saturation (O2crits) category (“no”, “maybe” or “yes”) for each fish by expert assessor (Elizabeth C. Hoots [ech], Jake M. Martin [jmm], Luis L. Kuchenmülle [llk] Maryane Gradito [mg], Timothy D. Clark [tdc]). Each tile represents one fish-expert pairing, colour-coded by assigned category: no (red, #E03C32), maybe (yellow, #FFD301), and yes (green, #7BB662).

Expert deviation from the majority assessment ranged from 22.41 to 6.90%.

expert deviations deviation_rate
ech 13 22.41
jmm 8 13.79
llk 6 10.34
tdc 5 8.62
mg 4 6.90

Let’s make a list of those that had majority assigned as yes for an O2crit. There was 10 total.

## [1] "Based on the majority visual assessment 10 fish have possible O₂crit."

O₂crit numbers

We will now check to see which fish have O2crit based on the numerical and visual inspections.

There are eight fish that both numerically and visually were determined to have a O2crit. Two fish with a visually confirmed O2crit, that did not meet the numerical criteria. Eight fish meet the numerical criteria, but did not pass the visual inspection.

## $Shared
## [1] "a_0_26nov_4" "b_0_24nov_1" "b_0_25nov_1" "b_0_25nov_3" "b_0_26nov_1"
## [6] "b_9_21nov_1" "b_9_21nov_2" "b_9_21nov_3"
## 
## $Unique_to_visual
## [1] "c_0_21nov_4" "d_0_21nov_2"
## 
## $Unique_to_numerical
## [1] "a_9_21nov_3" "b_0_24nov_2" "b_0_26nov_3" "b_9_22nov_1" "c_0_21nov_2"
## [6] "c_9_24nov_2" "d_0_21nov_3" "d_9_25nov_3"

How many per salinity treatment

salinity_group n
0 5
9 3

📈 Results

Looking at mean O2crit estimates.

n_o2crit mean_o2crit min_o2crit max_o2crit mean_mass mean_rel_mass sd_mass sd_rel_mass
8.00 24.94 19.10 32.00 0.46 0.85 0.18 0.34
mean_min_do sd_min_do min_min_do
13.12 3.23 8.82
salinity_group n_o2crit mean_o2crit min_o2crit max_o2crit mean_mass
0 5 25.32 19.1 32.0 0.3540000
9 3 24.30 21.7 28.9 0.6466667

Figure S8

These are the 8 fish that meet numerical criteria and passed visual inspection.

Figure S8: Representative examples of fish that were best modelled by a 2nd- or 3rd-order polynomial and meet the numerical inclusion criteria. The horizontal solid orange line shows the standard metabolic rate (SMR), the horizontal solid pink line shows thelowestMO2 (as defined by Claireaux and Chabot (2016)), the solid/dashed blue/green slope line shows the O2 regulation failure regression (based on the rule-based linear regression method of Claireaux and Chabot (2016); where the colour and line type indicate the type of regression fitted, through orgin or not), and the solid vertical blue/green line shows the O2crit estimate (intersection of O2 failure regression and SMR).

Pulling model method and lethal points

Figure S9

Making a O2crit plot for each of the eight fish that past visual and numerical assessment on the same axis.

Figure S9: Oxygen consumption rate (ṀO₂; mg⁻¹ O₂ h⁻¹) and ambient dissolved oxygen (DO; % saturation) plotted for each fish that passed both past visual and numerical assessment for O2crit. The horizontal dashed lines show SMR, the solid sloped lines represent the linear best fit for ṀO values below regulatory failure. The vertical soild lines represent O2crit (the intersection of the linear best fit for ṀO values below regulatory failure and SMR).

Figure 2

Let’s make some example plots for each major types of O2-MO2 relationships (i.e. 0th-, 1st-, and 2nd/3rd- order polynomial).

First an example of a 0th-order polynomial fit (c_9_24nov_4).

Second an example of a 1st-order polynomial best fit (d_9_25nov_3).

Last an example of a fish best fit with a higher order polynomial (2nd-order).

Let’s combined them in one plot

Figure 2: Figure 2. Representative examples of fish that were best modelled by a 0th-order polynomial (A), 1st-order polynomial (B), and 2nd-order polynomial (C). The orange dashed line shows the SMR, while the blue dashed line shows the theoretical oxyconfroming regression. For plot (C), the red sloped line shows the O2 regulation failure regression (based on the rule-based linear regression method of Claireaux and Chabot, 2016), and the solid horizontal green line shows the O2crit estimate (intersection of O2 failure regression and SMR).

Comapring to past data

Here, we have recreated a similar plot to that presented in Urbina, Glover, and Forster (2012)[1] and have extracted the mean level data from Figure 1a using the metaDigitise package in R[3]. This data is called urbina_et_al_2012. This allows us to compare the differences in Mo2 and the relationship between Mo2 and O2.

First making a binned data frame to match Urbina, Glover, and Forster (2012) as closely as possible.

Figure 3

Now the plot with our mean data and the mean data from Urbina, Glover, and Forster (2012)[1]

Figure 3: Mean and standard error of metabolic rate (MO2 μmol O2 g-1 h-1) and oxygen concentration (PO2 kPa) using 12 evenly spaced bins over the O2 range of observed data (blue filled dots). Compared against the mean and standard error reported in Urbina (2012)[1] (red open dots). The grey dots are the raw observed data form the present study.

📚 References

[1] Claireaux, G. and Chabot, D. (2016) Responses by fishes to environmental hypoxia: integration through Fry’s concept of aerobic metabolic scope. Journal of Fish Biology https://doi.org/10.1111/jfb.12833

[2] Urbina MA, Glover CN, and Forster ME, (2012) A novel oxyconforming response in the freshwater fish Galaxias maculatus. Comparative Biochemistry and Physiology Part A: Molecular & Integrative Physiology. https://doi.org/10.1016/j.cbpa.2011.11.011

[3] Pick JL, Nakagawa S, and Noble DWA (2018) Reproducible, flexible and high-throughput data extraction from primary literature: The metaDigitise r package. https://doi.org/10.1111/2041-210X.13118

💻 Session information

## 
## To cite R in publications use:
## 
##   R Core Team (2023). R: A language and environment for statistical
##   computing. R Foundation for Statistical Computing, Vienna, Austria.
##   URL https://www.R-project.org/.
## 
## A BibTeX entry for LaTeX users is
## 
##   @Manual{,
##     title = {R: A Language and Environment for Statistical Computing},
##     author = {{R Core Team}},
##     organization = {R Foundation for Statistical Computing},
##     address = {Vienna, Austria},
##     year = {2023},
##     url = {https://www.R-project.org/},
##   }
## 
## We have invested a lot of time and effort in creating R, please cite it
## when using it for data analysis. See also 'citation("pkgname")' for
## citing R packages.

Here is a detailed list of the session information

## ─ Session info ───────────────────────────────────────────────────────────────
##  setting  value
##  version  R version 4.2.3 (2023-03-15 ucrt)
##  os       Windows 10 x64 (build 19044)
##  system   x86_64, mingw32
##  ui       RTerm
##  language (EN)
##  collate  English_Australia.utf8
##  ctype    English_Australia.utf8
##  tz       Australia/Sydney
##  date     2025-05-28
##  pandoc   3.1.1 @ C:/Program Files/RStudio/resources/app/bin/quarto/bin/tools/ (via rmarkdown)
## 
## ─ Packages ───────────────────────────────────────────────────────────────────
##  package           * version  date (UTC) lib source
##  abind               1.4-5    2016-07-21 [1] CRAN (R 4.2.0)
##  arrayhelpers        1.1-0    2020-02-04 [1] CRAN (R 4.2.3)
##  backports           1.4.1    2021-12-13 [1] CRAN (R 4.2.0)
##  bayesplot         * 1.11.1   2024-02-15 [1] CRAN (R 4.2.3)
##  bitops              1.0-7    2021-04-24 [1] CRAN (R 4.2.0)
##  bridgesampling      1.1-2    2021-04-16 [1] CRAN (R 4.2.3)
##  brms              * 2.21.0   2024-03-20 [1] CRAN (R 4.2.3)
##  Brobdingnag         1.2-9    2022-10-19 [1] CRAN (R 4.2.3)
##  broom               1.0.4    2023-03-11 [1] CRAN (R 4.2.3)
##  broom.helpers       1.15.0   2024-04-05 [1] CRAN (R 4.2.3)
##  broom.mixed       * 0.2.9.5  2024-04-01 [1] CRAN (R 4.2.3)
##  bslib               0.7.0    2024-03-29 [1] CRAN (R 4.2.3)
##  cachem              1.0.7    2023-02-24 [1] CRAN (R 4.2.3)
##  caTools             1.18.2   2021-03-28 [1] CRAN (R 4.2.3)
##  cellranger          1.1.0    2016-07-27 [1] CRAN (R 4.2.3)
##  checkmate           2.3.1    2023-12-04 [1] CRAN (R 4.2.3)
##  cli                 3.6.4    2025-02-13 [1] CRAN (R 4.2.3)
##  coda                0.19-4.1 2024-01-31 [1] CRAN (R 4.2.3)
##  codetools           0.2-19   2023-02-01 [2] CRAN (R 4.2.3)
##  colorspace          2.1-0    2023-01-23 [1] CRAN (R 4.2.3)
##  crosstalk           1.2.1    2023-11-23 [1] CRAN (R 4.2.3)
##  curl                5.2.1    2024-03-01 [1] CRAN (R 4.2.3)
##  data.table        * 1.17.0   2025-02-22 [1] CRAN (R 4.2.3)
##  DEoptimR            1.1-3    2023-10-07 [1] CRAN (R 4.2.3)
##  devtools          * 2.4.5    2022-10-11 [1] CRAN (R 4.2.3)
##  digest              0.6.35   2024-03-11 [1] CRAN (R 4.2.3)
##  distributional      0.4.0    2024-02-07 [1] CRAN (R 4.2.3)
##  doParallel          1.0.17   2022-02-07 [1] CRAN (R 4.2.3)
##  dplyr             * 1.1.4    2023-11-17 [1] CRAN (R 4.2.3)
##  ellipsis            0.3.2    2021-04-29 [1] CRAN (R 4.2.3)
##  emmeans           * 1.11.0   2025-03-20 [1] CRAN (R 4.2.3)
##  estimability        1.5.1    2024-05-12 [1] CRAN (R 4.2.3)
##  evaluate            0.24.0   2024-06-10 [1] CRAN (R 4.2.3)
##  fansi               1.0.4    2023-01-22 [1] CRAN (R 4.2.3)
##  farver              2.1.1    2022-07-06 [1] CRAN (R 4.2.3)
##  fastmap             1.1.1    2023-02-24 [1] CRAN (R 4.2.3)
##  forcats           * 1.0.0    2023-01-29 [1] CRAN (R 4.2.3)
##  foreach             1.5.2    2022-02-02 [1] CRAN (R 4.2.3)
##  fs                  1.6.4    2024-04-25 [1] CRAN (R 4.2.3)
##  furrr               0.3.1    2022-08-15 [1] CRAN (R 4.2.3)
##  future            * 1.33.2   2024-03-26 [1] CRAN (R 4.2.3)
##  generics            0.1.3    2022-07-05 [1] CRAN (R 4.2.3)
##  ggdist              3.3.2    2024-03-05 [1] CRAN (R 4.2.3)
##  ggplot2           * 3.5.1    2024-04-23 [1] CRAN (R 4.2.3)
##  ggthemes          * 5.1.0    2024-02-10 [1] CRAN (R 4.2.3)
##  globals             0.16.3   2024-03-08 [1] CRAN (R 4.2.3)
##  glue                1.8.0    2024-09-30 [1] CRAN (R 4.2.3)
##  gridExtra         * 2.3      2017-09-09 [1] CRAN (R 4.2.3)
##  gsw                 1.2-0    2024-08-19 [1] CRAN (R 4.2.3)
##  gt                * 0.11.0   2024-07-09 [1] CRAN (R 4.2.3)
##  gtable              0.3.5    2024-04-22 [1] CRAN (R 4.2.3)
##  gtsummary         * 1.7.2    2023-07-15 [1] CRAN (R 4.2.3)
##  highr               0.11     2024-05-26 [1] CRAN (R 4.2.3)
##  hms               * 1.1.3    2023-03-21 [1] CRAN (R 4.2.3)
##  htmltools           0.5.8.1  2024-04-04 [1] CRAN (R 4.2.3)
##  htmlwidgets         1.6.4    2023-12-06 [1] CRAN (R 4.2.3)
##  httpuv              1.6.9    2023-02-14 [1] CRAN (R 4.2.3)
##  httr                1.4.7    2023-08-15 [1] CRAN (R 4.2.3)
##  inline              0.3.19   2021-05-31 [1] CRAN (R 4.2.3)
##  insight             1.1.0    2025-03-01 [1] CRAN (R 4.2.3)
##  iterators           1.0.14   2022-02-05 [1] CRAN (R 4.2.3)
##  janitor           * 2.2.0    2023-02-02 [1] CRAN (R 4.2.3)
##  jquerylib           0.1.4    2021-04-26 [1] CRAN (R 4.2.3)
##  jsonlite            1.8.8    2023-12-04 [1] CRAN (R 4.2.3)
##  knitr               1.42     2023-01-25 [1] CRAN (R 4.2.3)
##  labeling            0.4.3    2023-08-29 [1] CRAN (R 4.2.3)
##  later               1.3.0    2021-08-18 [1] CRAN (R 4.2.3)
##  lattice             0.20-45  2021-09-22 [2] CRAN (R 4.2.3)
##  lazyeval            0.2.2    2019-03-15 [1] CRAN (R 4.2.3)
##  lifecycle           1.0.4    2023-11-07 [1] CRAN (R 4.2.3)
##  listenv             0.9.1    2024-01-29 [1] CRAN (R 4.2.3)
##  loo                 2.8.0    2024-07-03 [1] CRAN (R 4.2.3)
##  lubridate         * 1.9.2    2023-02-10 [1] CRAN (R 4.2.3)
##  magrittr            2.0.3    2022-03-30 [1] CRAN (R 4.2.3)
##  marginaleffects   * 0.21.0   2024-06-14 [1] CRAN (R 4.2.3)
##  MASS                7.3-58.2 2023-01-23 [2] CRAN (R 4.2.3)
##  Matrix              1.5-3    2022-11-11 [2] CRAN (R 4.2.3)
##  matrixStats         1.3.0    2024-04-11 [1] CRAN (R 4.2.3)
##  mclust            * 6.1.1    2024-04-29 [1] CRAN (R 4.2.3)
##  memoise             2.0.1    2021-11-26 [1] CRAN (R 4.2.3)
##  mgcv                1.9-1    2023-12-21 [1] CRAN (R 4.2.3)
##  mime                0.12     2021-09-28 [1] CRAN (R 4.2.0)
##  miniUI              0.1.1.1  2018-05-18 [1] CRAN (R 4.2.3)
##  multcomp            1.4-25   2023-06-20 [1] CRAN (R 4.2.3)
##  munsell             0.5.1    2024-04-01 [1] CRAN (R 4.2.3)
##  mvtnorm             1.2-5    2024-05-21 [1] CRAN (R 4.2.3)
##  nlme                3.1-162  2023-01-31 [2] CRAN (R 4.2.3)
##  oce                 1.8-3    2024-08-17 [1] CRAN (R 4.2.3)
##  opdisDownsampling   1.0.1    2024-04-15 [1] CRAN (R 4.2.3)
##  pacman              0.5.1    2019-03-11 [1] CRAN (R 4.2.3)
##  parallelly          1.37.1   2024-02-29 [1] CRAN (R 4.2.3)
##  patchwork           1.2.0    2024-01-08 [1] CRAN (R 4.2.3)
##  pbmcapply           1.5.1    2022-04-28 [1] CRAN (R 4.2.0)
##  performance       * 0.12.0   2024-06-08 [1] CRAN (R 4.2.3)
##  pillar              1.9.0    2023-03-22 [1] CRAN (R 4.2.3)
##  pkgbuild            1.4.4    2024-03-17 [1] CRAN (R 4.2.3)
##  pkgconfig           2.0.3    2019-09-22 [1] CRAN (R 4.2.3)
##  pkgload             1.3.4    2024-01-16 [1] CRAN (R 4.2.3)
##  plotly            * 4.10.4   2024-01-13 [1] CRAN (R 4.2.3)
##  plyr                1.8.8    2022-11-11 [1] CRAN (R 4.2.3)
##  posterior           1.6.0    2024-07-03 [1] CRAN (R 4.2.3)
##  pracma              2.4.4    2023-11-10 [1] CRAN (R 4.2.3)
##  profvis             0.3.8    2023-05-02 [1] CRAN (R 4.2.3)
##  promises            1.2.0.1  2021-02-11 [1] CRAN (R 4.2.3)
##  purrr             * 1.0.1    2023-01-10 [1] CRAN (R 4.2.3)
##  qqconf              1.3.2    2023-04-14 [1] CRAN (R 4.2.3)
##  qqplotr           * 0.0.6    2023-01-25 [1] CRAN (R 4.2.3)
##  QuickJSR            1.3.0    2024-07-08 [1] CRAN (R 4.2.3)
##  R6                  2.5.1    2021-08-19 [1] CRAN (R 4.2.3)
##  RColorBrewer        1.1-3    2022-04-03 [1] CRAN (R 4.2.0)
##  Rcpp              * 1.0.10   2023-01-22 [1] CRAN (R 4.2.3)
##  RcppParallel        5.1.8    2024-07-06 [1] CRAN (R 4.2.3)
##  readr             * 2.1.4    2023-02-10 [1] CRAN (R 4.2.3)
##  readxl            * 1.4.3    2023-07-06 [1] CRAN (R 4.2.3)
##  remotes             2.5.0    2024-03-17 [1] CRAN (R 4.2.3)
##  reshape2            1.4.4    2020-04-09 [1] CRAN (R 4.2.3)
##  respirometry      * 2.0.0    2024-07-18 [1] CRAN (R 4.2.3)
##  rlang               1.1.5    2025-01-17 [1] CRAN (R 4.2.3)
##  rmarkdown           2.21     2023-03-26 [1] CRAN (R 4.2.3)
##  robustbase          0.99-4-1 2024-09-27 [1] CRAN (R 4.2.3)
##  rstan             * 2.32.6   2024-03-05 [1] CRAN (R 4.2.3)
##  rstantools          2.4.0    2024-01-31 [1] CRAN (R 4.2.3)
##  rstudioapi          0.14     2022-08-22 [1] CRAN (R 4.2.3)
##  sandwich            3.1-0    2023-12-11 [1] CRAN (R 4.2.3)
##  sass                0.4.9    2024-03-15 [1] CRAN (R 4.2.3)
##  scales              1.3.0    2023-11-28 [1] CRAN (R 4.2.3)
##  sessioninfo         1.2.2    2021-12-06 [1] CRAN (R 4.2.3)
##  shiny               1.8.1.1  2024-04-02 [1] CRAN (R 4.2.3)
##  snakecase           0.11.1   2023-08-27 [1] CRAN (R 4.2.3)
##  StanHeaders       * 2.32.9   2024-05-29 [1] CRAN (R 4.2.3)
##  stringi             1.7.12   2023-01-11 [1] CRAN (R 4.2.2)
##  stringr           * 1.5.1    2023-11-14 [1] CRAN (R 4.2.3)
##  survival            3.5-3    2023-02-12 [2] CRAN (R 4.2.3)
##  svUnit              1.0.6    2021-04-19 [1] CRAN (R 4.2.3)
##  tensorA             0.36.2.1 2023-12-13 [1] CRAN (R 4.2.3)
##  TH.data             1.1-2    2023-04-17 [1] CRAN (R 4.2.3)
##  tibble            * 3.2.1    2023-03-20 [1] CRAN (R 4.2.3)
##  tidybayes         * 3.0.6    2023-08-12 [1] CRAN (R 4.2.3)
##  tidyr             * 1.3.0    2023-01-24 [1] CRAN (R 4.2.3)
##  tidyselect          1.2.1    2024-03-11 [1] CRAN (R 4.2.3)
##  tidyverse         * 2.0.0    2023-02-22 [1] CRAN (R 4.2.3)
##  timechange          0.2.0    2023-01-11 [1] CRAN (R 4.2.3)
##  twosamples          2.0.1    2023-06-23 [1] CRAN (R 4.2.3)
##  tzdb                0.3.0    2022-03-28 [1] CRAN (R 4.2.3)
##  urlchecker          1.0.1    2021-11-30 [1] CRAN (R 4.2.3)
##  usethis           * 2.2.3    2024-02-19 [1] CRAN (R 4.2.3)
##  utf8                1.2.3    2023-01-31 [1] CRAN (R 4.2.3)
##  V8                  4.4.2    2024-02-15 [1] CRAN (R 4.2.3)
##  vctrs               0.6.5    2023-12-01 [1] CRAN (R 4.2.3)
##  viridisLite         0.4.2    2023-05-02 [1] CRAN (R 4.2.3)
##  withr               3.0.0    2024-01-16 [1] CRAN (R 4.2.3)
##  xfun                0.38     2023-03-24 [1] CRAN (R 4.2.3)
##  xml2                1.3.6    2023-12-04 [1] CRAN (R 4.2.3)
##  xtable              1.8-4    2019-04-21 [1] CRAN (R 4.2.3)
##  yaml                2.3.7    2023-01-23 [1] CRAN (R 4.2.3)
##  zoo                 1.8-12   2023-04-13 [1] CRAN (R 4.2.3)
## 
##  [1] C:/R
##  [2] C:/Program Files/R/R-4.2.3/library
## 
## ──────────────────────────────────────────────────────────────────────────────
LS0tDQp0aXRsZTogIlRoZSByb2xlIG9mIG9zbW9yZXNwaXJhdG9yeSBjb21wcm9taXNlIGluIG1ldGFib2xpc20gYW5kIGh5cG94aWEgdG9sZXJhbmNlIG9mIGEgcHVycG9ydGVkbHkgb3h5Y29uZm9ybWluZyB0ZWxlb3N0Ig0KYXV0aG9yOiAiSmFrZSBNYXJ0aW4iDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiAlWScpYCINCm91dHB1dDoNCiAgIyBwZGZfZG9jdW1lbnQ6DQogICMgICB0b2M6IHRydWUNCiAgIyAgIGxhdGV4X2VuZ2luZTogeGVsYXRleA0KICAjICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICMgICBwYW5kb2NfYXJnczogWyItLXZhcmlhYmxlPWRvY3VtZW50Y2xhc3M6YXJ0aWNsZSJdDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGRlcHRoOiA0DQogICAgbnVtYmVyX3NlY3Rpb25zOiBubw0KICAgIHRoZW1lOiAgY29zbW8NCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDogeWVzDQogICAgdG9jX2RlcHRoOiA0DQprbml0OiB8DQogIChmdW5jdGlvbihpbnB1dCwgLi4uKSB7DQogICAgb3V0cHV0X3BhdGggPC0gcm1hcmtkb3duOjpyZW5kZXIoDQogICAgICBpbnB1dCwNCiAgICAgIG91dHB1dF9maWxlID0gJ2luZGV4Lmh0bWwnLA0KICAgICAgZW52aXIgPSBnbG9iYWxlbnYoKQ0KICAgICkNCiAgICBmaWxlLmNvcHkob3V0cHV0X3BhdGgsICJzdXBwbGVtZW50YXJ5LWZpbGUtMS5odG1sIiwgb3ZlcndyaXRlID0gVFJVRSkNCiAgICBvdXRwdXRfcGF0aA0KICB9KQ0KLS0tDQoNClshW0xpY2Vuc2U6IENDIEJZIDQuMF0oaHR0cHM6Ly9pbWcuc2hpZWxkcy5pby9iYWRnZS9MaWNlbnNlLUNDJTIwQlklMjA0LjAtbGlnaHRncmV5LnN2ZyldKGh0dHBzOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9ieS80LjAvKSANCg0KPCEtLSBDb21tZW50IG91dCB0aGUgbGljZW5zZSB3aGVuIGtuaXR0aW5nIHRvIFBERiAtLT4NCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQojIPCfk5UgUkVBRCBNRQ0KDQo8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+DQoNCioqU1VNTUFSWSoqDQpUaGlzIFIgY29kZSBlc3RpbWF0ZXMgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIG94eWdlbiBjb25zdW1wdGlvbiAoTU/igoIpIGFuZCBkaXNzb2x2ZWQgb3h5Z2VuIHNhdHVyYXRpb24gKERPKSBpbiB0aGUgQ29tbW9uIEdhbGF4aWFzICgqR2FsYXhpYXMgbWFjdWxhdHVzKikuIEl0IGFsc28gZXN0aW1hdGVzIHRoZSBjcml0aWNhbCBveHlnZW4gc2F0dXJhdGlvbiB2YWx1ZSBmb3IgYWVyb2JpYyBtZXRhYm9saXNtIE88c3ViPjJjcml0PC9zdWI+LCBjb21tb25seSBkZWZpbmVkIGFzIHRoZSB0aHJlc2hvbGQgYmVsb3cgd2hpY2ggdGhlIG94eWdlbiBjb25zdW1wdGlvbiByYXRlIGNhbiBubyBsb25nZXIgYmUgc3VzdGFpbmVkLiBUaGUgYXNzb2NpYXRlZCBhcnRpY2xlIGlzIHRpdGxlZCAqIlRoZSByb2xlIG9mIG9zbW9yZXNwaXJhdG9yeSBjb21wcm9taXNlIGluIG1ldGFib2xpc20gYW5kIGh5cG94aWEgdG9sZXJhbmNlIG9mIGEgcHVycG9ydGVkbHkgb3h5Y29uZm9ybWluZyB0ZWxlb3N0LiIqIElmIHlvdSBhcmUgcmVhZGluZyB0aGUgSFRNTCB2ZXJzaW9uIG9mIHRoaXMgc2NyaXB0LCBjbGljayB0aGUgYENvZGVgIGJ1dHRvbiBpbiB0aGUgdG9wIHJpZ2h0IHRvIGRvd25sb2FkIHRoZSBgLlJtZGAgZmlsZS4NCg0KKipBSU0qKg0KVGhlIGFydGljbGUgYWltcyB0byB0ZXN0IHdoZXRoZXIgKkdhbGF4aWFzIG1hY3VsYXR1cyogY2FuIG1haW50YWluIG94eWdlbiBjb25zdW1wdGlvbiAoTU/igoIpIGFzIGFtYmllbnQgRE8gZGVjbGluZXMgYW5kLCBpZiBzbywgYXQgd2hhdCBsZXZlbCBpdCByZWFjaGVzIHRoZSBjcml0aWNhbCBveHlnZW4gc2F0dXJhdGlvbiB2YWx1ZSBmb3IgYWVyb2JpYyBtZXRhYm9saXNtIChPPHN1Yj4yY3JpdDwvc3ViPikuDQoNCioqQVVUSE9SUyoqDQpUaW1vdGh5IEQuIENsYXJrIF5bYV1eDQpMdWlzIEwuIEt1Y2hlbm3DvGxsZXIgXlthXV4NCkVsaXphYmV0aCBDLiBIb290cyBeW2FdXg0KTWFyeWFuZSBHcmFkaXRvIF5bYV1eDQpKYWtlIE0uIE1hcnRpbiBeW2EsYl1eDQoNCioqQUZGSUxJQVRJT05TKioNClthXSBTY2hvb2wgb2YgTGlmZSBhbmQgRW52aXJvbm1lbnRhbCBTY2llbmNlcywgRGVha2luIFVuaXZlcnNpdHksIEdlZWxvbmcsIFZJQywgQXVzdHJhbGlhXA0KW2JdIERlcGFydG1lbnQgb2YgV2lsZGxpZmUsIEZpc2ggYW5kIEVudmlyb25tZW50YWwgU3R1ZGllcywgU3dlZGlzaCBVbml2ZXJzaXR5IG9mIEFncmljdWx0dXJhbCBTY2llbmNlcywgVW1lw6UsIFN3ZWRlblwNCg0KDQoqKkRJU0NMQUlNRVIqKg0KSSAoSmFrZSBNYXJ0aW4pIGFtIGR5c2xleGljLiBJIGhhdmUgbWFkZSBhbiBlZmZvcnQgdG8gcmV2aWV3IHRoZSBzY3JpcHQgZm9yIGdyYW1tYXRpY2FsIGVycm9ycywgYnV0IHNvbWUgd2lsbCBsaWtlbHkgcmVtYWluLiBJIGFwb2xvZ2lzZS4gUGxlYXNlIGZlZWwgZnJlZSB0byByZWFjaCBvdXQgdXNpbmcgdGhlIGNvbnRhY3QgZGV0YWlscyBiZWxvdyBpZiBhbnl0aGluZyBpcyB1bmNsZWFyLg0KDQo8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+DQoNCiMg8J+TpyBDb250YWN0DQoNCjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT4NCg0KKipKYWtlIE0uIE1hcnRpbioqDQoNCvCfk6cgKipFbWFpbDoqKiBbamFrZS5tYXJ0aW5cQGRlYWtpbi5lZHUuYXVdKG1haWx0bzpqYWtlLm1hcnRpbkBkZWFraW4uZWR1LmF1KQ0KDQrwn5OnICoqQWx0IEVtYWlsOioqIFtqYWtlLm1hcnRpbi5yZXNlYXJjaFxAZ21haWwuY29tXShtYWlsdG86amFrZS5tYXJ0aW4ucmVzZWFyY2hAZ21haWwuY29tKQ0KDQrwn4yQICoqV2ViOioqIFtqYWtlbWFydGluLm9yZ10oaHR0cHM6Ly9qYWtlbWFydGluLm9yZy8pDQoNCvCfkJkgKipHaXRIdWIqKjogW0pha2VNYXJ0aW5SZXNlYXJjaF0oaHR0cHM6Ly9naXRodWIuY29tL0pha2VNYXJ0aW5SZXNlYXJjaCkNCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQojIPCfk5EgU2hhcmluZy9hY2Nlc3NpbmcgYW5kIGNpdGluZw0KDQo8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+DQoNCjEuICAqKkxpY2Vuc2VzL3Jlc3RyaWN0aW9ucyBwbGFjZWQgb24gdGhlIGRhdGE6KiogQ0MtQlkgNC4wDQoNCjIuICAqKkxpbmsgdG8gdGhlIGFzc29jaWF0ZWQgcHVibGljYXRpb246KipcDQogICAg8J+apyAqKipUbyBiZSBhZGRlZCoqKiDwn5qnDQoNCjMuICAqKlJlY29tbWVuZGVkIGNpdGF0aW9uIGZvciB0aGlzIGRhdGE6KipcDQoNCkNsYXJrLCBULiBELiwgS3VjaGVubcO8bGxlciwgTC4gTC4sIEhvb3RzLCBFLiBDLiwgR3JhZGl0bywgTS4sICYgTWFydGluLCBKLiBNLiAoMjAyNSwgTWF5IDI4KS4gVGhlIHJvbGUgb2Ygb3Ntb3Jlc3BpcmF0b3J5IGNvbXByb21pc2UgaW4gaHlwb3hpYSB0b2xlcmFuY2Ugb2YgdGhlIHB1cnBvcnRlZGx5IG94eWNvbmZvcm1pbmcgdGVsZW9zdCBHYWxheGlhcyBtYWN1bGF0dXMuIGh0dHBzOi8vZG9pLm9yZy8xMC4xNzYwNS9PU0YuSU8vR0ZYQ0ENCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQojIPCfk6YgUmVxdWlyZWQgcGFja2FnZXMgYW5kIGtuaXQgc2V0dGluZ3MNCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQpBIGxpc3Qgb2YgdGhlIHJlcXVpcmVkIHBhY2thZ2VzIHRvIHJ1biB0aGUgc2NyaXB0Lg0KDQpgYGB7ciBzZXR1cH0NCg0KIyAtLS0tLSBQYWNrYWdlcyAtLS0tLS0NCmlmICghcmVxdWlyZU5hbWVzcGFjZSgicGFjbWFuIiwgcXVpZXRseSA9IFRSVUUpKSBpbnN0YWxsLnBhY2thZ2VzKCJwYWNtYW4iKQ0KDQojIC0tLS0gTGlzdCBvZiByZXF1aXJlZCBwYWNrYWdlcyAtLS0tDQpwa2dzIDwtIGMoDQogICMgLS0tLS0gRGF0YSBWaXN1YWxpc2F0aW9uIC0tLS0tDQogICJnZ3RoZW1lcyIsICJiYXllc3Bsb3QiLCAiZ3QiLCAiZ3RzdW1tYXJ5IiwgInBsb3RseSIsICJxcXBsb3RyIiwgImdyaWRFeHRyYSIsDQogIA0KICAjIC0tLS0tIFRpZHkgRGF0YSBhbmQgV3JhbmdsaW5nIC0tLS0tDQogICJ0aWR5dmVyc2UiLCAiamFuaXRvciIsICJyZWFkeGwiLCAiYnJvb20ubWl4ZWQiLCAiZGF0YS50YWJsZSIsICJobXMiLCAiZGV2dG9vbHMiLA0KICAibWNsdXN0IiwNCiAgDQogICMgLS0tLS0gTW9kZWxsaW5nIGFuZCBTdGF0aXN0aWNhbCBBbmFseXNpcyAtLS0tLQ0KICAiYnJtcyIsICJyc3RhbiIsICJtYXJnaW5hbGVmZmVjdHMiLCAicGVyZm9ybWFuY2UiLCAiZW1tZWFucyIsDQogICJ0aWR5YmF5ZXMiLCAicmVzcGlyb21ldHJ5IiwgImZ1dHVyZSINCikNCg0KIyAtLS0tIEluc3RhbGwgYW5kIGxvYWQgYWxsIHBhY2thZ2VzIHVzaW5nIHBhY21hbiAtLS0tDQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMoDQogIHBhY21hbjo6cF9sb2FkKGNoYXIgPSBwa2dzLCBpbnN0YWxsID0gVFJVRSkNCikNCg0KIy0tLS0tLS1rbml0ZXIgc2VldHRpbmctLS0tLS0tLS0tLQ0KDQprbml0cjo6b3B0c19jaHVuayRzZXQoDQogIGVjaG8gPSBGQUxTRSwgIyBvbmx5IGZvciBQREYga25pdA0KICBtZXNzYWdlID0gRkFMU0UsDQogIHdhcm5pbmcgPSBGQUxTRSwgIyBubyB3YXJuaW5ncw0KICBjYWNoZSA9IFRSVUUsIyBjYWNoZWluZyB0byBzYXZlIHRpbWUgd2hlbiBrbml0aW5nDQogIHRpZHkgPSBUUlVFLA0KICBmaWcuYWxpZ24gPSAiY2VudGVyIiANCikNCmBgYA0KDQoNCjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT4NCg0KIyDwn5SnIEN1c3RvbSBmdW5jdGlvbnMNCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQpIZXJlIGFyZSBzb21lIGN1c3RvbSBmdW5jdGlvbnMgdXNlZCB3aXRoaW4gdGhpcyBzY3JpcHQuDQoNCmBiYXllc19pbmNyZW1lbnRhbF9yZWdyZXNzaW9uX2J5X2lkKClgOiBBIGN1c3RvbSBmdW5jdGlvbiB0byBidWlsZCBCYXllc2lhbiBpbmNyZW1lbnRhbCByZWdyZXNzaW9ucy4gSXQgaXMgZGVzaWduZWQgdG8gcnVuIGEgbGlzdCBvZiBzdWJncm91cCBtb2RlbHMgKElEcykgaW4gcGFyYWxsZWwgdXNpbmcgNCBjb3Jlcy4gVGhlIGZ1bmN0aW9uIHVzZXMgYGJybSgpYCB3aXRoIGEgR2F1c3NpYW4gZXJyb3IgZGlzdHJpYnV0aW9uLg0KDQoqKlVzZSoqOlwNClRoZSBmdW5jdGlvbiBhY2NlcHRzIHRoZSBmb2xsb3dpbmcgYXJndW1lbnRzOlwNCi0gYGlkX2lgOiBBIGdyb3VwaW5nIGZhY3RvciBvciBJRCB1c2VkIHRvIGZpbHRlciB0aGUgZGF0YSBmb3IgZWFjaCByZWdyZXNzaW9uLiBJZiBub25lIGlzIHByb3ZpZGVkLCB0aGUgZnVuY3Rpb24gdXNlcyB0aGUgZW50aXJlIGRhdGFzZXQuXA0KLSBgaWRfbmFtZWA6IFRoZSBjb2x1bW4gbmFtZSAoYXMgYSBjaGFyYWN0ZXIgc3RyaW5nKSBjb3JyZXNwb25kaW5nIHRvIHRoZSBncm91cGluZyBmYWN0b3IgaW4gdGhlIGRhdGEgZnJhbWUuIElmIG5vdCBwcm92aWRlZCwgdGhlIGZ1bmN0aW9uIHVzZXMgYWxsIGRhdGEuXA0KLSBgZGF0YWA6IFRoZSBkYXRhIGZyYW1lIGNvbnRhaW5pbmcgdGhlIHZhcmlhYmxlcyBmb3IgYW5hbHlzaXMuXA0KLSBgcHJlZGljdG9yYDogVGhlIHByZWRpY3RvciB2YXJpYWJsZSBvZiBpbnRlcmVzdC5cDQotIGByZXNwb25zZWA6IFRoZSByZXNwb25zZSB2YXJpYWJsZSBvZiBpbnRlcmVzdC5cDQotIGBzZWVkX251bWJlcmA6IEEgcmFuZG9tIHNlZWQgdmFsdWUgZm9yIG1vZGVsIHJlcHJvZHVjaWJpbGl0eS5cDQotIGBzYXZlX21vZGVsc2A6IEEgbG9naWNhbCBhcmd1bWVudCBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gc2F2ZSB0aGUgbW9kZWwgb3V0cHV0cyAoYFRSVUVgIG9yIGBGQUxTRWApLlwNCi0gYG1vZF9vdXRwdXRfd2RgOiBUaGUgb3V0cHV0IGRpcmVjdG9yeSB3aGVyZSBtb2RlbCBgLnJkc2AgZmlsZXMgc2hvdWxkIGJlIHNhdmVkICh1c2VkIG9ubHkgaWYgYHNhdmVfbW9kZWxzID0gVFJVRWApLg0KDQpgYGB7cn0NCiMgSW5zdGVhZCB3ZSBjb3VsZCBhbHNvIHVzZSBhIGRpc3RyaWJ1dGlvbmFsIHJlZ3Jlc3Npb24gYXBwcm9hY2gsIGJ5IHNwZWNpZmljYWxseSBtb2RlbGxpbmcgdGhlIHZhcmlhbmNlIGJ5IERPIChlLmcuIHNpZ21hIH4gRE8pLiBXZWlnaHRpbmcgbWF5IG5vdCBiZSByZXF1aXJlZCBpbiB0aGlzIGNhc2UsIEkgZG9uJ3QgdGhpbmsgaGlnaGVyIGRlbnNpdHkgb2YgdmFsdWVzIGluIGEgZ2l2ZW4gc3BhY2Ugd2lsbCBlZmZlY3QgQmF5ZXNpYW4gZXN0aW1hdGVzIGxpa2UgaXQgZG9lcyBpbiBmcmVxdWVudGlzdCBtb2RlbHMuIFNlZSBkaXNjb3Vyc2UgaHR0cHM6Ly9kaXNjb3Vyc2UubWMtc3Rhbi5vcmcvdC93ZWlnaHRzLWluLWJybS80Mjc4ICAgDQoNCmJheWVzX2luY3JlbWVudGFsX3JlZ3Jlc3Npb25fYnlfaWQgPC0gZnVuY3Rpb24oaWRfaSwgaWRfbmFtZSwgZGF0YSwgcHJlZGljdG9yLCByZXNwb25zZSwgc2VlZF9udW1iZXIsIHNhdmVfbW9kZWxzLCBtb2Rfb3V0cHV0X3dkKSB7DQogICMgSW5pdGlhdGUgYW4gZW1wdHkgbGlzdCB0byBzdG9yZSBtb2RlbHMNCiAgbW9kZWxzIDwtIGxpc3QoKQ0KICANCiAgIyBDaGVjayBpZiBpZF9uYW1lIGlzIG1pc3NpbmcsIE5VTEwsIG9yIGJsYW5rLCBhbmQgYXNzaWduIE5BIGlmIHNvDQogIGlmIChtaXNzaW5nKGlkX25hbWUpIHx8IGlzLm51bGwoaWRfbmFtZSkgfHwgaWRfbmFtZSA9PSAiIikgew0KICAgIGlkX25hbWUgPC0gTkENCiAgfQ0KICANCiAgIyBDaGVjayBpZiBpZF9pIGlzIG1pc3NpbmcsIE5VTEwsIG9yIGJsYW5rLCBhbmQgYXNzaWduIE5BIGlmIHNvDQogIGlmIChtaXNzaW5nKGlkX2kpIHx8IGlzLm51bGwoaWRfaSkgfHwgaWRfaSA9PSAiIikgew0KICAgIGlkX25hbWUgPC0gTkENCiAgfQ0KICANCiAgIyBGaWx0ZXIgZGF0YSBmb3IgdGhlIGN1cnJlbnQgSUQgaWYgaWRfbmFtZSBpcyBnaXZlbiBhcyBhIGZhY3RvciBvciBjaGFyYWN0ZXIgYW5kIGlkX2kgaXMgZGVmaW5lZA0KICBkZl9pIDwtIGRhdGEgJT4lDQogICAgZHBseXI6OmZpbHRlcigNCiAgICAgIGlmICghaXMubmEoaWRfaSkgJiYgKGlzLmZhY3RvcihkYXRhW1tpZF9uYW1lXV0pIHx8IGlzLmNoYXJhY3RlcihkYXRhW1tpZF9uYW1lXV0pKSkgew0KICAgICAgICAhIXJsYW5nOjpzeW0oaWRfbmFtZSkgPT0gaWRfaQ0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgVFJVRQ0KICAgICAgfQ0KICAgICkNCiAgDQogICMgRHluYW1pY2FsbHkgY3JlYXRlIGZvcm11bGFzDQogIGZvcm11bGFfbG1fMCA8LSByZWZvcm11bGF0ZSgiMSIsIHJlc3BvbnNlKQ0KICBmb3JtdWxhX2xtXzEgPC0gcmVmb3JtdWxhdGUocHJlZGljdG9yLCByZXNwb25zZSkNCiAgZm9ybXVsYV9sbV8yIDwtIHJlZm9ybXVsYXRlKHNwcmludGYoInBvbHkoJXMsIDIpIiwgcHJlZGljdG9yKSwgcmVzcG9uc2UpDQogIGZvcm11bGFfbG1fMyA8LSByZWZvcm11bGF0ZShzcHJpbnRmKCJwb2x5KCVzLCAzKSIsIHByZWRpY3RvciksIHJlc3BvbnNlKQ0KICANCiAgIyBGaXQgYW5kIHN0b3JlIG1vZGVscyBpbiB0aGUgbGlzdA0KICBtb2RlbHNbW3Bhc3RlMChpZF9pLCAiX2xtXzAiKV1dIDwtIGJybSgNCiAgICBiZihmb3JtdWxhX2xtXzAsIGZhbWlseSA9IGdhdXNzaWFuKCkpLCANCiAgICBkYXRhID0gZGZfaSwgY29yZXMgPSA0LCBzZWVkID0gc2VlZF9udW1iZXIsIHNhdmVfcGFycyA9IHNhdmVfcGFycyhhbGwgPSBzYXZlX21vZGVscyksDQogICAgc2FtcGxlX3ByaW9yID0gRkFMU0UsIHNpbGVudCA9IFRSVUUsIGZpbGUgPSBwYXN0ZTAobW9kX291dHB1dF93ZCwgIi8iLCBpZF9pLCAiX2xtXzAiKQ0KICApDQogIA0KICBtb2RlbHNbW3Bhc3RlMChpZF9pLCAiX2xtXzEiKV1dIDwtIGJybSgNCiAgICBiZihmb3JtdWxhX2xtXzEsIGZhbWlseSA9IGdhdXNzaWFuKCkpLCANCiAgICBkYXRhID0gZGZfaSwgY29yZXMgPSA0LCBzZWVkID0gc2VlZF9udW1iZXIsIHNhdmVfcGFycyA9IHNhdmVfcGFycyhhbGwgPSBzYXZlX21vZGVscyksDQogICAgc2FtcGxlX3ByaW9yID0gRkFMU0UsIHNpbGVudCA9IFRSVUUsIGZpbGUgPSBwYXN0ZTAobW9kX291dHB1dF93ZCwgIi8iLCBpZF9pLCAiX2xtXzEiKQ0KICApDQogIA0KICBtb2RlbHNbW3Bhc3RlMChpZF9pLCAiX2xtXzIiKV1dIDwtIGJybSgNCiAgICBiZihmb3JtdWxhX2xtXzIsIGZhbWlseSA9IGdhdXNzaWFuKCkpLCANCiAgICBkYXRhID0gZGZfaSwgY29yZXMgPSA0LCBzZWVkID0gc2VlZF9udW1iZXIsIHNhdmVfcGFycyA9IHNhdmVfcGFycyhhbGwgPSBzYXZlX21vZGVscyksDQogICAgc2FtcGxlX3ByaW9yID0gRkFMU0UsIHNpbGVudCA9IFRSVUUsIGZpbGUgPSBwYXN0ZTAobW9kX291dHB1dF93ZCwgIi8iLCBpZF9pLCAiX2xtXzIiKQ0KICApDQogIA0KICBtb2RlbHNbW3Bhc3RlMChpZF9pLCAiX2xtXzMiKV1dIDwtIGJybSgNCiAgICBiZihmb3JtdWxhX2xtXzMsIGZhbWlseSA9IGdhdXNzaWFuKCkpLCANCiAgICBkYXRhID0gZGZfaSwgY29yZXMgPSA0LCBzZWVkID0gMTQzMDE5LCBzYXZlX3BhcnMgPSBzYXZlX3BhcnMoYWxsID0gc2F2ZV9tb2RlbHMpLA0KICAgIHNhbXBsZV9wcmlvciA9IEZBTFNFLCBzaWxlbnQgPSBUUlVFLCBmaWxlID0gcGFzdGUwKG1vZF9vdXRwdXRfd2QsICIvIiwgaWRfaSwgIl9sbV8zIikNCiAgKQ0KICANCiAgIyBSZXR1cm4gdGhlIGxpc3Qgb2YgbW9kZWxzIGZvciB0aGUgY3VycmVudCBJRA0KICByZXR1cm4obW9kZWxzKQ0KfQ0KYGBgDQoNCmBsb2FkX3JkczkoKWA6IEEgY3VzdG9tIGZ1bmN0aW9uIHRvIGxvYWQgYWxsIHJkcyBtb2RlbHMgaW4gYSBkaXJlY3RvcnkgYW5kIHN0b3JlIGluIGEgbGlzdC4gVGFrZXMgYSBkaXJlY3Rvcnkgd2l0aCBgLnJkc2AgZmlsZXMNCg0KYGBge3J9DQpsb2FkX3JkcyA8LSBmdW5jdGlvbihtb2RlbF9kdykgew0KICAjIExpc3QgYWxsIC5yZHMgZmlsZXMgaW4gdGhlIGRpcmVjdG9yeQ0KICBtb2RlbF9maWxlX2xpc3QgPC0gbGlzdC5maWxlcyhwYXRoID0gbW9kZWxfZHcsIHBhdHRlcm4gPSAiXFwucmRzJCIsIGZ1bGwubmFtZXMgPSBUUlVFKQ0KICANCiAgIyBTdHJpcCBleHRlbnNpb25zIGFuZCBnZXQgbmFtZXMNCiAgbW9kZWxfbmFtZXMgPC0gdG9vbHM6OmZpbGVfcGF0aF9zYW5zX2V4dChiYXNlbmFtZShtb2RlbF9maWxlX2xpc3QpKQ0KICANCiAgIyBSZWFkIGFsbCAucmRzIGZpbGVzIGludG8gYSBuYW1lZCBsaXN0DQogIG1vZGVsX3N0b3JlX2xpc3QgPC0gc2V0TmFtZXMobGFwcGx5KG1vZGVsX2ZpbGVfbGlzdCwgcmVhZFJEUyksIG1vZGVsX25hbWVzKQ0KICANCiAgcmV0dXJuKG1vZGVsX3N0b3JlX2xpc3QpDQp9DQpgYGANCg0KYGluY3JlbWVudGFsX3JlZ3Jlc3Npb25fYmF5ZXNfZml0cygpYDogQSBjdXN0b20gZnVuY3Rpb24gZm9yIHB1bGxpbmcgbW9kZWwgZml0cywgbG9vIGFuZCByMiB1c2luZyBgbG9vKClgIGFuZCBgYmF5ZXNfUjIoKWAsIHJlc3BlY3RpdmVseS4gVGFrZXMgYSBsaXN0IG9mIGBicm1gIG1vZGVscy4NCg0KYGBge3J9DQojIERlZmluZSBGdW5jdGlvbiB0byBQcm9jZXNzIHRoZSBkYXRhIGZvciBlYWNoIElEDQppbmNyZW1lbnRhbF9yZWdyZXNzaW9uX2JheWVzX2ZpdHMgPC0gZnVuY3Rpb24obW9kZWxzKSB7DQogIA0KICBsb29fcmVzdWx0c19saXN0IDwtIGxpc3QoKQ0KICANCiAgIyBJdGVyYXRlIG92ZXIgdGhlIG5hbWVzIG9mIHRoZSBtb2RlbHMNCiAgZm9yIChtb2RfbmFtZSBpbiBuYW1lcyhtb2RlbHMpKSB7DQogICAgIyBFeHRyYWN0IHRoZSBtb2RlbA0KICAgIG1vZF9pIDwtIG1vZGVsc1tbbW9kX25hbWVdXQ0KICAgIA0KICAgICMgQ29tcHV0ZSBMT08gcmVzdWx0cw0KICAgIG1vZF9sb29fcmVzdWx0c19pIDwtIGxvbzo6bG9vKG1vZF9pKQ0KICAgIA0KICAgICMgRXh0cmFjdCByZWxldmFudCBMT08gbWV0cmljcw0KICAgIGVscGRfbG9vX2kgPC0gbW9kX2xvb19yZXN1bHRzX2kkZWxwZF9sb28NCiAgICBwX2xvb19pIDwtIG1vZF9sb29fcmVzdWx0c19pJHBfbG9vDQogICAgbG9vaWNfaSA8LSBtb2RfbG9vX3Jlc3VsdHNfaSRsb29pYw0KICAgIA0KICAgICMgQ3JlYXRlIGEgZGF0YSBmcmFtZSB3aXRoIG1ldHJpY3MNCiAgICBkZl9pIDwtIGRhdGEuZnJhbWUoDQogICAgICBlbHBkX2xvbyA9IGVscGRfbG9vX2ksDQogICAgICBwX2xvbyA9IHBfbG9vX2ksDQogICAgICBsb29pYyA9IGxvb2ljX2ksDQogICAgICBtb2RlbCA9IG1vZF9uYW1lDQogICAgKQ0KICAgIA0KICAgIGVzdF9pIDwtIHRpZHkobW9kX2ksIGVmZmVjdHMgPSAiZml4ZWQiLCBjb25mLmludCA9IFRSVUUpICU+JSANCiAgICAgIGRwbHlyOjpzZWxlY3QodGVybSwgZXN0aW1hdGUsIGNvbmYubG93LCBjb25mLmhpZ2gpICU+JSANCiAgICAgIHRpZHlyOjpwaXZvdF93aWRlcigNCiAgICAgICAgbmFtZXNfZnJvbSA9IHRlcm0sICAgICAgICAgICAgICAgICMgVXNlIGB0ZXJtYCBhcyBjb2x1bW4gbmFtZXMNCiAgICAgICAgdmFsdWVzX2Zyb20gPSBjKGVzdGltYXRlLCBjb25mLmxvdywgY29uZi5oaWdoKSwgICMgVmFsdWVzIHRvIHBpdm90DQogICAgICAgIG5hbWVzX3NlcCA9ICJfIiAgICAgICAgICAgICAgICAgICAjIEFkZCBhIHNlcGFyYXRvciB0byBjb2x1bW4gbmFtZXMNCiAgICAgICkNCiAgICANCiAgICBkZl9pIDwtIGNiaW5kKGRmX2ksIGVzdF9pKQ0KICAgIA0KICAgICMgU3RvcmUgdGhlIGRhdGEgZnJhbWUgaW4gdGhlIGxpc3QNCiAgICBsb29fcmVzdWx0c19saXN0W1ttb2RfbmFtZV1dIDwtIGRmX2kNCiAgfQ0KICANCiAgIyBDb21iaW5kIA0KICBsb29fcmVzdWx0c19jb21iaW5lZCA8LSBiaW5kX3Jvd3MobG9vX3Jlc3VsdHNfbGlzdCkNCiAgDQogICMgR2V0IFIyIA0KICByMl9yZXN1bHRzIDwtIG1hcF9kZnIobW9kZWxzLCB+IGFzLmRhdGEuZnJhbWUoYmF5ZXNfUjIoLngpKSwgLmlkID0gIm1vZGVsIikgJT4lDQogICAgdGliYmxlOjpyZW1vdmVfcm93bmFtZXMoKQ0KICANCiAgIyBDb21iaW5kIFIyIGFuZCBsb28gcmVzdWx0cyANCiAgbW9kZWxfZml0X2RmIDwtIGRwbHlyOjpmdWxsX2pvaW4obG9vX3Jlc3VsdHNfY29tYmluZWQsIHIyX3Jlc3VsdHMsIGJ5ID0gIm1vZGVsIikgJT4lIA0KICAgIGRwbHlyOjpzZWxlY3QobW9kZWwsIGV2ZXJ5dGhpbmcoKSkgJT4lIA0KICAgIGRwbHlyOjpyZW5hbWUocjIgPSBFc3RpbWF0ZSwNCiAgICAgICAgICAgICAgICAgIHIyX2Vycm9yID0gRXN0LkVycm9yLA0KICAgICAgICAgICAgICAgICAgcjJfcTIuNSA9IFEyLjUsDQogICAgICAgICAgICAgICAgICByMl9xOTcuNSA9IFE5Ny41KSAlPiUgDQogICAgZHBseXI6Om11dGF0ZShpZCA9IHN1YigiXyhsbV9cXGQrKSQiLCAiIiwgbW9kZWwpLA0KICAgICAgICAgICAgICAgICAgbW9kZWxfdHlwZSA9IHN1YigiXi4qXyhsbV9cXGQrKSQiLCAiXFwxIiwgbW9kZWwpKQ0KICANCiAgcmV0dXJuKG1vZGVsX2ZpdF9kZikNCn0NCmBgYA0KDQpgYmF5ZXNfbW9kX3ByZWRpY3Rpb25zKClgOiBUaGlzIGZ1bmN0aW9uIGV4dHJhY3RzIHRoZSBwcmVkaWN0ZWQgdmFsdWVzIHVzaW5nIGBmaXR0ZWQoKWAgZnJvbSBhIGxpc3Qgb2YgbW9kZWxzIGFuZCBjb21iaW5lcyB0aGVtIHdpdGggdGhlIG9yaWdpbmFsIGRhdGEgZmlsZSB1c2VkIGZvciB0aGUgbW9kZWwuIFRoZXNlIGFyZSB0aGUgKipwb3N0ZXJpb3IgbWVhbiBmaXR0ZWQgdmFsdWVzKiogKGkuZS4gdGhlIGV4cGVjdGVkIHZhbHVlIG9mIHRoZSByZXNwb25zZSB2YXJpYWJsZSBnaXZlbiB0aGUgcHJlZGljdG9yIHZhcmlhYmxlcyBhbmQgdGhlIGVzdGltYXRlZCBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9ucyBvZiB0aGUgcGFyYW1ldGVycykgZm9yIGVhY2ggb2JzZXJ2YXRpb24gaW4gdGhlIGRhdGFzZXQsIGFsb25nIHdpdGggKio5NSUgY3JlZGlibGUgaW50ZXJ2YWxzKiouDQoNCmBgYHtyfQ0KYmF5ZXNfbW9kX3ByZWRpY3Rpb25zIDwtIGZ1bmN0aW9uKG1vZGVscywgb3JpZ2luYWxfZGF0YSkgew0KICANCiAgcHJlZGljdGlvbl9saXN0IDwtIGxpc3QoKQ0KICANCiAgZm9yIChtb2RfbmFtZSBpbiBuYW1lcyhtb2RlbHMpKSB7DQogICAgIyBFeHRyYWN0IG1vZA0KICAgIG1vZF9pIDwtIG1vZGVsc1tbbW9kX25hbWVdXQ0KICAgIA0KICAgICMgTWFrZSBtb2RlIHByZWRpY3Rpb25zDQogICAgbW9kZWxfcHJlZGljdGlvbnNfaSA8LSBhcy5kYXRhLmZyYW1lKGZpdHRlZChtb2RfaSwgc3VtbWFyeSA9IFRSVUUpKSAlPiUgDQogICAgICBkcGx5cjo6bXV0YXRlKG1vZGVsID0gbW9kX25hbWUsDQogICAgICAgICAgICAgICAgICAgIGlkID0gc3ViKCJfKGxtX1xcZCspJCIsICIiLCBtb2RfbmFtZSksDQogICAgICAgICAgICAgICAgICAgIG1vZGVsX3R5cGUgPSBzdWIoIl4uKl8obG1fXFxkKykkIiwgIlxcMSIsIG1vZF9uYW1lKSkgJT4lIA0KICAgICAgZHBseXI6OnJlbmFtZShwcmVkX2xvd2VyID0gUTIuNSwgcHJlZF91cHBlciA9IFE5Ny41LCBwcmVkaWN0ZWQgPSBFc3RpbWF0ZSwgcHJlZF9lcnJvciA9IEVzdC5FcnJvcikgJT4lIA0KICAgICAgZHBseXI6OnNlbGVjdChtb2RlbCwgZXZlcnl0aGluZygpKQ0KICAgIA0KICAgIGlkX2kgPC0gbW9kZWxfcHJlZGljdGlvbnNfaSRpZFsxXQ0KICAgIA0KICAgIG9yaWdpbmFsX2RhdGFfaSA8LSBvcmlnaW5hbF9kYXRhICU+JSANCiAgICAgIGRwbHlyOjpmaWx0ZXIoaWQgPT0gaWRfaSkgJT4lIA0KICAgICAgZHBseXI6OnNlbGVjdCgtaWQpDQogICAgDQogICAgbW9kZWxfcHJlZGljdGlvbnNfb3JpZ2luYWxfaSA8LSBjYmluZChtb2RlbF9wcmVkaWN0aW9uc19pLCBvcmlnaW5hbF9kYXRhX2kpDQogICAgDQogICAgcHJlZGljdGlvbl9saXN0W1ttb2RfbmFtZV1dIDwtIG1vZGVsX3ByZWRpY3Rpb25zX29yaWdpbmFsX2kNCiAgfQ0KICBwcmVkaWN0aW9uc19kZiA8LSBiaW5kX3Jvd3MocHJlZGljdGlvbl9saXN0KSANCiAgcmV0dXJuKHByZWRpY3Rpb25zX2RmKQ0KfQ0KYGBgDQoNCmBjYWxjU01SKClgOiAqKmF1dGhvcmVkIGJ5IERlbmlzIENoYWJvdCoqIHVzZWQgdG8gZXN0aW1hdGUgU01SIHdpdGggc2V2ZXJhbCBkaWZmZXJlbnQgbWV0aG9kcyBDbGFpcmVhdXggYW5kIENoYWJvdCAoMjAxNikgXlsxXV4NCg0KXlsxXV4gQ2xhaXJlYXV4LCBHLiBhbmQgQ2hhYm90LCBELiAoMjAxNikgUmVzcG9uc2VzIGJ5IGZpc2hlcyB0byBlbnZpcm9ubWVudGFsIGh5cG94aWE6IGludGVncmF0aW9uIHRocm91Z2ggRnJ5J3MgY29uY2VwdCBvZiBhZXJvYmljIG1ldGFib2xpYyBzY29wZS4gSm91cm5hbCBvZiBGaXNoIEJpb2xvZ3kgPGh0dHBzOi8vZG9pLm9yZy8xMC4xMTExL2pmYi4xMjgzMz4NCg0KYGBge3J9DQpjYWxjU01SID0gZnVuY3Rpb24oWSwgcT1jKDAuMSwwLjE1LDAuMiwwLjI1LDAuMyksIEc9MTo0KXsNCgl1ID0gc29ydChZKQ0KCXRoZS5NY2x1c3QgPC0gTWNsdXN0KFksICBHPUcpDQoJY2wgPC0gdGhlLk1jbHVzdCRjbGFzc2lmaWNhdGlvbg0KCSMgc29tZXRpbWVzLCB0aGUgY2xhc3MgY29udGFpbmluZyBTTVIgaXMgbm90IGNhbGxlZCAxDQoJIyB0aGUgZm9sbG93aW5nIHByZXN1bWVzIHRoYXQgd2hlbiBjbGFzcyAxIGNvbnRhaW5zID4gMTAlIG9mIGNhc2VzLCANCgkjIGl0IGNvbnRhaW5zIFNNUiwgb3RoZXJ3aXNlIHdlIHRha2UgY2xhc3MgMg0KCWNsMiA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKGNsKSkNCgljbDIkY2wgPC0gYXMubnVtZXJpYyhsZXZlbHMoY2wyJGNsKSkNCgl2YWxpZCA8LSBjbDIkRnJlcT49MC4xKmxlbmd0aCh0aW1lKSAgDQoJdGhlLmNsIDwtIG1pbihjbDIkY2xbdmFsaWRdKQ0KCWxlZnQuZGlzdHIgPC0gWVt0aGUuTWNsdXN0JGNsYXNzaWZpY2F0aW9uPT10aGUuY2xdDQoJbWxuZCA9IHRoZS5NY2x1c3QkcGFyYW1ldGVycyRtZWFuW3RoZS5jbF0NCglDVm1sbmQgPSBzZChsZWZ0LmRpc3RyKS9tbG5kICogMTAwDQoJcXVhbnQ9cXVhbnRpbGUoWSwgcSkNCglsb3cxMD1tZWFuKHVbMToxMF0pDQoJbG93MTBwYyA9IG1lYW4odVs2Oig1ICsgcm91bmQoMC4xKihsZW5ndGgodSktNSkpKV0pDQoJIyByZW1vdmUgNSBvdXRsaWVycywga2VlcCBsb3dlc3QgMTAlIG9mIHRoZSByZXN0LCBhdmVyYWdlDQoJIyBIZXJybWFubiAmIEVuZGVycyAyMDAwDQoJcmV0dXJuKGxpc3QobWxuZD1tbG5kLCBxdWFudD1xdWFudCwgbG93MTA9bG93MTAsIGxvdzEwcGM9bG93MTBwYywNCgkJICAgICAgY2w9Y2wsIENWbWxuZD1DVm1sbmQpKQ0KfQ0KYGBgDQoNCmBjYWxjTzJjcml0KClgOiAqKmF1dGhvcmVkIGJ5IERlbmlzIENoYWJvdCoqIHVzZWQgdG8gZXN0aW1hdGUgTzJjcml0IChQY3JpcHQpLiBDbGFpcmVhdXggYW5kIENoYWJvdCAoMjAxNikgXlsxXV4NCg0KKioqTm90ZTogTzIgaXMgYXNzdW1lZCB0byBiZSBpbiBwZXJjZW50YWdlIG9mIGRpc3NvbHZlZCBveHlnZW4gKERPKSoqKg0KDQpgYGB7cn0NCmNhbGNPMmNyaXQgPC0gZnVuY3Rpb24oRGF0YSwgU01SLCBsb3dlc3RNTzIgPSBOQSwgZ2FwTGltaXQgPSA0LA0KbWF4Lm5iLk1PMi5mb3IucmVnID0gMjApDQp7DQojIEFVVEhPUjogRGVuaXMgQ2hhYm90LCBJbnN0aXR1dCBNYXVyaWNlLUxhbW9udGFnbmUsIERGTywgQ2FuYWRhDQojIGZpcnN0IHZlcnNpb24gd3JpdHRlbiBpbiBKdW5lIDIwMDkNCiMgbGFzdCB1cGRhdGVkIGluIEphbnVhcnkgMjAxNQ0KbWV0aG9kID0gIkxTX3JlZyIgIyB3aWxsIGJlY29tZSAidGhyb3VnaF9vcmlnaW4iIGlmIGludGVyY2VwdCBpcyA+IDANCmlmKGlzLm5hKGxvd2VzdE1PMikpIGxvd2VzdE1PMiA9IHF1YW50aWxlKERhdGEkTU8yW0RhdGEkRE8gPj0gODBdLCBwPTAuMDUpDQojIFN0ZXAgMTogaWRlbnRpZnkgcG9pbnRzIHdoZXJlIE1PMiBpcyBwcm9wb3J0aW9uYWwgdG8gRE8NCmdlcVNNUiA9IERhdGEkTU8yID49IGxvd2VzdE1PMg0KcGl2b3RETyA9IG1pbihEYXRhJERPW2dlcVNNUl0pDQpsZXRoYWwgPSBEYXRhJERPIDwgcGl2b3RETw0KTl91bmRlcl9TTVIgPSBzdW0obGV0aGFsKSAjIHBvaW50cyBhdmFpbGFibGUgZm9yIHJlZ3Jlc3Npb24/DQpmaW5hbF9OX3VuZGVyX1NNUiA9IGxldGhhbCAjIHNvbWUgcG9pbnRzIG1heSBiZSByZW1vdmVkIGF0IFN0ZXAgNA0KbGFzdE1PMnJlZyA9IERhdGEkTU8yW0RhdGEkRE8gPT0gcGl2b3RET10gIyBsYXN0IE1PMiB3aGVuIHJlZ3VsYXRpbmcNCmlmKE5fdW5kZXJfU01SID4gMSkgdGhlTW9kID0gbG0oTU8yfkRPLCBkYXRhPURhdGFbbGV0aGFsLF0pDQojIFN0ZXAgMiwgYWRkIG9uZSBvciBtb3JlIHBvaW50IGF0IG9yIGFib3ZlIFNNUg0KIyAyQSwgd2hlbiB0aGVyZSBhcmUgZmV3ZXIgdGhhbiAzIHZhbGlkIHBvaW50cyB0byBjYWxjdWxhdGUgYSByZWdyZXNzaW9uDQppZihOX3VuZGVyX1NNUiA8IDMpew0KbWlzc2luZyA9IDMgLSBzdW0obGV0aGFsKQ0Kbm90LmxldGhhbCA9IERhdGEkRE9bZ2VxU01SXQ0KRE9saW1pdCA9IG1heChzb3J0KG5vdC5sZXRoYWwpWzE6bWlzc2luZ10pICMgaGlnaGVzdCBETyBhY2NlcHRhYmxlDQojIHRvIHJlYWNoIGEgTiBvZiAzDQphZGRlZFBvaW50cyA9IERhdGEkRE8gPD0gRE9saW1pdA0KbGV0aGFsID0gbGV0aGFsIHwgYWRkZWRQb2ludHMNCnRoZU1vZCA9IGxtKE1PMn5ETywgZGF0YT1EYXRhW2xldGhhbCxdKQ0KfQ0KIyAyQiwgYWRkIHBpdm90RE8gdG8gdGhlIGZpdCB3aGVuIFN0ZXAgMSB5aWVsZGVkIDMgb3IgbW9yZSB2YWx1ZXM/DQppZihOX3VuZGVyX1NNUiA+PSAzKXsNCmxldGhhbEIgPSBEYXRhJERPIDw9IHBpdm90RE8gIyBoYXMgb25lIG1vcmUgdmFsdWUgdGhhbiAibGV0aGFsIg0KcmVnQSA9IHRoZU1vZA0KcmVnQiA9IGxtKE1PMn5ETywgZGF0YT1EYXRhW2xldGhhbEIsXSkNCmxhcmdlX3Nsb3BlX2Ryb3AgPSAoY29lZihyZWdBKVsyXS9jb2VmKHJlZ0IpWzJdKSA+IDEuMSAjIGFyYml0cmFyeQ0KbGFyZ2VfRE9fZ2FwID0gKG1heChEYXRhJERPW2xldGhhbEJdKSAtIG1heChEYXRhJERPW2xldGhhbF0pKSA+IGdhcExpbWl0DQp0b29TbWFsbE1PMiA9IGxhc3RNTzJyZWcgPCBTTVINCmlmKCFsYXJnZV9zbG9wZV9kcm9wICYgIWxhcmdlX0RPX2dhcCAmICF0b29TbWFsbE1PMikgew0KbGV0aGFsID0gbGV0aGFsQg0KdGhlTW9kID0gcmVnQg0KfSAjIG90aGVyd2lzZSB3ZSBkbyBub3QgYWNjZXB0IHRoZSBhZGRpdGlvbmFsIHBvaW50DQp9DQojIFN0ZXAgMw0KIyBpZiB0aGUgdXNlciB3YW50cyB0byBsaW1pdCB0aGUgbnVtYmVyIG9mIHBvaW50cyBpbiB0aGUgcmVncmVzc2lvbg0KaWYoIWlzLm5hKG1heC5uYi5NTzIuZm9yLnJlZykgJiBzdW0obGV0aGFsKT5tYXgubmIuTU8yLmZvci5yZWcpew0KUmFua3MgPSByYW5rKERhdGEkRE8pDQpsZXRoYWwgPSBSYW5rcyA8PSBtYXgubmIuTU8yLmZvci5yZWcNCnRoZU1vZCA9IGxtKE1PMn5ETywgZGF0YT1EYXRhW2xldGhhbCxdKQ0KZmluYWxfTl91bmRlcl9TTVIgPSBtYXgubmIuTU8yLmZvci5yZWcNCn0NCiMgU3RlcCA0DQpwcmVkTU8yID0gYXMubnVtZXJpYyhwcmVkaWN0KHRoZU1vZCwgZGF0YS5mcmFtZShETz1EYXRhJERPKSkpDQpEYXRhJGRlbHRhID0gKERhdGEkTU8yLXByZWRNTzIpL3ByZWRNTzIgKiAxMDAgIyByZXNpZHVhbHMgc2V0IHRvIHplcm8NCiMgd2hlbiBiZWxvdyBwaXZvdERPDQpEYXRhJGRlbHRhW0RhdGEkRE8gPCBwaXZvdERPIHwgbGV0aGFsXSA9IDANCnRvbCA9IDAgIyBhbnkgcG9zaXRpdmUgcmVzaWR1YWwgaXMgdW5hY2NlcHRhYmxlDQpIaWdoVmFsdWVzID0gRGF0YSRkZWx0YSA+IHRvbA0KUmFua3MgPSByYW5rKC0xKkRhdGEkZGVsdGEpDQpIaWdoTU8yID0gSGlnaFZhbHVlcyAmIFJhbmtzID09IG1pbihSYW5rcykgIyBrZWVwIGxhcmdlc3QgcmVzaWR1YWwNCmlmIChzdW0oSGlnaFZhbHVlcykgPiAwKSB7DQpuYmxldGhhbCA9IHN1bShsZXRoYWwpDQpEYXRhJFcgPSBOQQ0KRGF0YSRXW2xldGhhbF09MS9uYmxldGhhbA0KRGF0YSRXW0hpZ2hNTzJdID0gMQ0KdGhlTW9kID0gbG0oTU8yfkRPLCB3ZWlnaHQ9VywgZGF0YT1EYXRhW2xldGhhbCB8IEhpZ2hNTzIsXSkNCiMgVGhpcyBuZXcgcmVncmVzc2lvbiBpcyBhbHdheXMgYW4gaW1wcm92ZW1lbnQsIGJ1dCB0aGVyZSBjYW4gc3RpbGwNCiMgYmUgcG9pbnRzIGFib3ZlIHRoZSBsaW5lLCBzbyB3ZSByZXBlYXQNCnByZWRNTzJfMiA9IGFzLm51bWVyaWMocHJlZGljdCh0aGVNb2QsIGRhdGEuZnJhbWUoRE89RGF0YSRETykpKQ0KRGF0YSRkZWx0YTIgPSAoRGF0YSRNTzItcHJlZE1PMl8yKS9wcmVkTU8yXzIgKiAxMDANCkRhdGEkZGVsdGEyW0RhdGEkRE8gPCBwaXZvdERPXSA9IDANCnRvbCA9IERhdGEkZGVsdGEyW0hpZ2hNTzJdDQpIaWdoVmFsdWVzMiA9IERhdGEkZGVsdGEyID4gdG9sDQppZihzdW0oSGlnaFZhbHVlczIpPjApew0KUmFua3MyID0gcmFuaygtMSpEYXRhJGRlbHRhMikNCkhpZ2hNTzJfMiA9IEhpZ2hWYWx1ZXMyICYgUmFua3MyID09IDEgIyBrZWVwIHRoZSBsYXJnZXN0IHJlc2lkdWFsDQpuYmxldGhhbCA9IHN1bShsZXRoYWwpDQpEYXRhJFcgPSBOQQ0KRGF0YSRXW2xldGhhbF09MS9uYmxldGhhbA0KRGF0YSRXW0hpZ2hNTzJfMl0gPSAxDQp0aGVNb2QyID0gbG0oTU8yfkRPLCB3ZWlnaHQ9VywgZGF0YT1EYXRhW2xldGhhbCB8IEhpZ2hNTzJfMixdKQ0KIyBpcyBuZXcgc2xvcGUgc3RlZXBlciB0aGFuIHRoZSBvbGQgb25lPw0KaWYodGhlTW9kMiRjb2VmWzJdID4gdGhlTW9kJGNvZWZbMl0pIHsNCnRoZU1vZCA9IHRoZU1vZDINCkhpZ2hNTzIgPSBIaWdoTU8yXzINCn0NCn0gIyBlbmQgc2Vjb25kIHNlYXJjaCBmb3IgaGlnaCB2YWx1ZQ0KfSAjIGVuZCBmaXJzdCBzZWFyY2ggZm9yIGhpZ2ggdmFsdWUNCkNvZWYgPSBjb2VmZmljaWVudHModGhlTW9kKQ0KI1N0ZXAgNSwgY2hlY2sgZm9yIHBvc2l0aXZlIGludGVyY2VwdA0KQWJvdmVPcmlnaW4gPSBDb2VmWzFdID4gMA0KIyBpZiBpdCBpcywgd2UgdXNlIGEgcmVncmVzc2lvbiB0aGF0IGdvZXMgdGhyb3VnaCB0aGUgb3JpZ2luDQppZiAoQWJvdmVPcmlnaW4pew0KdGhlTW9kID0gbG0oTU8yfkRPIC0xLCBkYXRhPURhdGFbbGV0aGFsLF0pDQpDb2VmID0gYygwLCBjb2VmZmljaWVudHModGhlTW9kKSkgIyBuZWVkIHRvIGFkZCB0aGUgaW50ZXJjZXB0ICgwKQ0KIyBtYW51YWxseSB0byBoYXZlIGEgcGFpciBvZiBjb2VmZmljaWVudHMNCm1ldGhvZCA9ICJ0aHJvdWdoX29yaWdpbiINCkhpZ2hNTzIgPSByZXAoRkFMU0UsIG5yb3coRGF0YSkpICMgZGlkIG5vdCB1c2UgdGhlIGFkZGl0aW9uYWwgdmFsdWUNCiMgZnJvbSBTdGVwIDQNCn0NCnBvMmNyaXQgPSBhcy5udW1lcmljKHJvdW5kKChTTVIgLSBDb2VmWzFdKSAvIENvZWZbMl0sIDEpKQ0Kc3VtX21vZCA9IHN1bW1hcnkodGhlTW9kKQ0KYW5vdl9tb2QgPSBhbm92YSh0aGVNb2QpDQpPMkNSSVQgPSBsaXN0KG8yY3JpdD1wbzJjcml0LCBTTVI9U01SLCBOYl9NTzJfY29uZm9ybWluZyA9IE5fdW5kZXJfU01SLA0KTmJfTU8yX2NvbmZfdXNlZCA9IGZpbmFsX05fdW5kZXJfU01SLA0KSGlnaF9NTzJfcmVxdWlyZWQgPSBzdW0oSGlnaE1PMikgPT0gMSwgb3JpZ0RhdGE9RGF0YSwNCk1ldGhvZD1tZXRob2QsIG1vZD10aGVNb2QsIHIyID0gc3VtX21vZCRyLnNxdWFyZWQsDQpQID0gYW5vdl9tb2QkIlByKD5GKSIsIGxldGhhbFBvaW50cyA9IHdoaWNoKGxldGhhbCksDQpBZGRlZFBvaW50cyA9IHdoaWNoKEhpZ2hNTzIpKQ0KfSAjIGVuZCBmdW5jdGlvbg0KYGBgDQoNCmBwbG90TzJjcml0KClgOiAqKmF1dGhvcmVkIGJ5IERlbmlzIENoYWJvdCoqLCB1c2VkIHRvIHBsb3QgdGhlIG1vZGVzIHVzZWQgZm9yIHRoZSBgY2FsY08yY3JpdCgpYCBmdW5jdGlvbi4gQ2xhaXJlYXV4IGFuZCBDaGFib3QgKDIwMTYpIF5bMV1eDQoNCioqKk5vdGU6IEkgYWRkZWQgYWJsaW5lKGg9bG93ZXN0TU8yLCBjb2w9InBpbmsiKSBzbyB0aGF0IEkgY291bGQgdmlzdWFsaXNlIHRoZSBsb3dlc3RNTzIgcG9zaXRpb24qKioNCg0KYGBge3J9DQpwbG90TzJjcml0IDwtIGZ1bmN0aW9uKG8yY3JpdG9iaiwgcGxvdElEPSIiLA0KWGxhYj0iRGlzc29sdmVkIG94eWdlbiAoJSBzYXQuKSIsIFlsYWI9ImRvdGl0YWx1bW9sIiwNCnNtci5jZXg9MC45LCBvMmNyaXQuY2V4PTAuOSwgcGxvdElELmNleD0xLjIsDQpUcmFuc3BhcmVuY3k9VCwuLi4pDQp7DQojIEFVVEhPUjogRGVuaXMgQ2hhYm90LCBJbnN0aXR1dCBNYXVyaWNlLUxhbW9udGFnbmUsIERGTywgQ2FuYWRhDQojIGZpcnN0IHZlcnNpb24gd3JpdHRlbiBpbiBKdW5lIDIwMDkNCiMgbGFzdCB1cGRhdGVkIDIwMTUtMDItMDkNCiMgZm9yIFIgcGxvdHRpbmcgZGV2aWNlcyB0aGF0IGRvIG5vdCBzdXBwb3J0IHRyYW5zcGFyZW5jeQ0KIyAoZS5nLiwgcG9zdHNjcmlwdCksIHNldCBUcmFuc3BhcmVuY3kgdG8gRkFMU0UNCnNtciA9IG8yY3JpdG9iaiRTTVINCmlmKFlsYWIgJWluJSBjKCJkb3RpdGFsdW1vbCIsICJpdGFsdW1vbCIsICJkb3R1bW9sIiwgInVtb2wiLA0KImRvdGl0YWxtZyIsICJpdGFsbWciLCAiZG90bWciLCAibWciKSkgew0Kc3dpdGNoKFlsYWIsDQpkb3RpdGFsdW1vbCA9IHsNCm1vMi5sYWIgPSBleHByZXNzaW9uKHBhc3RlKGl0YWxpYyhkb3QoTSkpW09bMl1dLCAiICgiLG11LCJtb2wgIiwgT1syXSwNCiIgIiwgbWluXi0xLCAiICIsIGtnXi0xLCAiKSIpKQ0KfSwNCml0YWx1bW9sID0gew0KbW8yLmxhYiA9IGV4cHJlc3Npb24ocGFzdGUoaXRhbGljKE0pW09bMl1dLCAiICgiLG11LCJtb2wgIiwgT1syXSwgIiAiLA0KbWluXi0xLCAiICIsIGtnXi0xLCAiKSIpKQ0KfSwNCmRvdHVtb2wgPSB7DQptbzIubGFiID0gZXhwcmVzc2lvbihwYXN0ZShkb3QoTSlbT1syXV0sICIgKCIsbXUsIm1vbCAiLCBPWzJdLCAiICIsDQptaW5eLTEsICIgIiwga2deLTEsICIpIikpDQp9LA0KdW1vbCA9IHsNCm1vMi5sYWIgPSBleHByZXNzaW9uKHBhc3RlKE1bT1syXV0sICIgKCIsbXUsIm1vbCAiLCBPWzJdLCAiICIsIG1pbl4tMSwNCiIgIiwga2deLTEsICIpIikpDQp9LA0KZG90aXRhbG1nID0gew0KbW8yLmxhYiA9IGV4cHJlc3Npb24ocGFzdGUoaXRhbGljKGRvdChNKSlbT1syXV0sICIgKG1nICIsIE9bMl0sICIgIiwNCmheLTEsICIgIiwga2deLTEsICIpIikpDQp9LA0KaXRhbG1nID0gew0KbW8yLmxhYiA9IGV4cHJlc3Npb24ocGFzdGUoaXRhbGljKE0pW09bMl1dLCAiIChtZyAiLCBPWzJdLCAiICIsDQpoXi0xLCAiICIsIGtnXi0xLCAiKSIpKQ0KfSwNCmRvdG1nID0gew0KbW8yLmxhYiA9IGV4cHJlc3Npb24ocGFzdGUoZG90KE0pW09bMl1dLCAiIChtZyAiLCBPWzJdLCAiICIsIGheLTEsICIgIiwNCmtnXi0xLCAiKSIpKQ0KfSwNCm1nID0gew0KbW8yLmxhYiA9IGV4cHJlc3Npb24ocGFzdGUoTVtPWzJdXSwgIiAobWcgIiwgT1syXSwgIiAiLCBoXi0xLCAiICIsDQprZ14tMSwgIikiKSkNCn0NCikNCn0gZWxzZSBtbzIubGFiPVlsYWINCmlmKFRyYW5zcGFyZW5jeSkge0NvbD1jKHJnYigwLDAsMCwwLjcpLCAicmVkIiwgIm9yYW5nZSIpDQp9IGVsc2Uge0NvbD1jKGdyZXkoMC4zKSwgInJlZCIsICJvcmFuZ2UiKX0NCkRhdGE9bzJjcml0b2JqJG9yaWdEYXRhDQpsb3dlc3RNTzIgPSBxdWFudGlsZShEYXRhJE1PMltEYXRhJERPID49IDgwXSwgcD0wLjA1KSAjIEkgYWRkZWQgdGhpcw0KRGF0YSRDb2xvciA9IENvbFsxXQ0KRGF0YSRDb2xvcltvMmNyaXRvYmokbGV0aGFsUG9pbnRzXSA9IENvbFsyXQ0KRGF0YSRDb2xvcltvMmNyaXRvYmokQWRkZWRQb2ludHNdID0gQ29sWzNdDQojIG9yZGluYXJ5IExTIHJlZ3Jlc3Npb24gd2l0aG91dCBhZGRlZCBwb2ludHM6IGJsdWUgbGluZSwgcmVkIHN5bWJvbHMNCiMgb3JkaW5hcnkgTFMgcmVncmVzc2lvbiB3aXRoIGFkZGVkIHBvaW50czogYmx1ZSBsaW5lLCByZWQgJiBvcmFuZ2Ugc3ltYm9scw0KIyByZWdyZXNzaW9uIHRocm91Z2ggb3JpZ2luOiBncmVlbiBkb3R0ZWQgbGluZSwgcmVkIHN5bWJvbHMNCmxpbmUuY29sb3IgPSBpZmVsc2UobzJjcml0b2JqJE1ldGhvZD09IkxTX3JlZyIsICJibHVlIiwgImRhcmtncmVlbiIpDQpsaW5lLnR5cGUgPSBpZmVsc2UobzJjcml0b2JqJE1ldGhvZD09IkxTX3JlZyIsIDEsIDMpDQpsaW1YID0gYygwLCBtYXgoRGF0YSRETykpDQpsaW1ZID0gYygwLCBtYXgoRGF0YSRNTzIpKQ0KcGxvdChNTzJ+RE8sIGRhdGE9RGF0YSwgeGxpbT1saW1YLCB5bGltPWxpbVksIGNvbD1EYXRhJENvbG9yLCB4bGFiPVhsYWIsDQp5bGFiPW1vMi5sYWIsIC4uLikNCmNvb3JkIDwtIHBhcigidXNyIikNCmlmKHBsb3RJRCAhPSAiIil7DQp0ZXh0KDAsIGNvb3JkWzRdLCBwbG90SUQsIGNleD1wbG90SUQuY2V4LCBhZGo9YygwLDEuMikpDQp9DQphYmxpbmUoaD1sb3dlc3RNTzIsIGNvbD0icGluayIpICMgSSBhZGRlZCB0aGlzDQphYmxpbmUoaD1zbXIsIGNvbD0ib3JhbmdlIikNCnRleHQoY29vcmRbMV0sIHNtciwgIlNNUiIsIGFkaj1jKC0wLjEsMS4zKSwgY2V4PXNtci5jZXgpDQp0ZXh0KGNvb3JkWzFdLCBzbXIsIHJvdW5kKHNtciwxKSwgYWRqPWMoLTAuMSwtMC4zKSwgY2V4PXNtci5jZXgpDQppZighaXMubmEobzJjcml0b2JqJG8yY3JpdCkpIHsNCmFibGluZShvMmNyaXRvYmokbW9kLCBjb2w9bGluZS5jb2xvciwgbHR5PWxpbmUudHlwZSkNCnNlZ21lbnRzKG8yY3JpdG9iaiRvMmNyaXQsIHNtciwgbzJjcml0b2JqJG8yY3JpdCwgY29vcmRbM10sDQpjb2w9bGluZS5jb2xvciwgbHdkPTEpDQp0ZXh0KHg9bzJjcml0b2JqJG8yY3JpdCwgeT0wLCBvMmNyaXRvYmokbzJjcml0LCBjb2w9bGluZS5jb2xvciwNCmNleD1vMmNyaXQuY2V4LCBhZGo9YygtMC4xLDAuNSkpDQp9DQp9ICMgZW5kIG9mIGZ1bmN0aW9uDQpgYGANCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQojIPCfk4IgRGlyZWN0b3JpZXMNCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQojIyBJbnB1dA0KDQoqKvCfk6UgaW5wdXRfZGF0YV93ZCoqOiBEaXJlY3RvcnkgZm9yIHRoZSBtZXRhZGF0YQ0KDQpgYGB7cn0NCndkIDwtIGdldHdkKCkNCmlucHV0X2RhdGFfd2QgPC0gcGFzdGUwKHdkLCAiLi9pbnB1dC1kYXRhIikgIyBjcmVhdGVzIGEgdmFyaWFibGUgd2l0aCB0aGUgbmFtZSBvZiB0aGUgd2Qgd2Ugd2FudCB0byB1c2UNCmBgYA0KDQoqKvCfk6UgbW9kX2RhdGFfd2QqKjogRGlyZWN0b3J5IGZvciBtb2RlbCBvdXRwdXQgZGF0YSBlc3RpbWF0ZWQgc2xvcGVzDQoNCmBgYHtyfQ0KbW9kX2RhdGFfd2QgPC0gcGFzdGUwKHdkLCAiLi9tb2QtZGF0YSIpDQpgYGANCg0KIyMgT3V0cHV0DQoNCioq8J+TpCBvdXRwdXRfZmlnX3dkKio6IHRoaXMgaXMgd2hlcmUgd2Ugd2lsbCBwdXQgdGhlIGZpZ3VyZXMNCg0KYGBge3J9DQpvdXRwdXRfZmlnX3dkIDwtIHBhc3RlMCh3ZCwgIi4vb3V0cHV0LWZpZyIpDQppZiAoIWRpci5leGlzdHMoIm91dHB1dC1maWciKSkge2Rpci5jcmVhdGUoIm91dHB1dC1maWciKX0NCmBgYA0KDQoqKvCfk6Qgb3V0cHV0X21vZHNfd2QqKjogdGhpcyBpcyB3aGVyZSB3ZSB3aWxsIHB1dCB0aGUgbW9kZWxzDQoNCmBgYHtyfQ0Kb3V0cHV0X21vZHNfd2QgPC0gcGFzdGUwKHdkLCAiLi9vdXRwdXQtbW9kIikNCmlmICghZGlyLmV4aXN0cygib3V0cHV0LW1vZCIpKSB7ZGlyLmNyZWF0ZSgib3V0cHV0LW1vZCIpfQ0KYGBgDQoNCjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT4NCg0KIyDwn5K/IERhdGENCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQojIyBTbG9wZXMgKOG5gE8pDQoNCioq8J+SvyBzbG9wZV9kZioqOiBXZSBoYXZlIGltcG9ydGVkIHRoZSBzbG9wZXMgZXh0cmFjdGVkIGluIExhYkNoYXJ0IGR1cmluZyBlYWNoIHBoYXNlIG9mIHRoZSBleHBlcmltZW50DQoNCmBgYHtyfQ0KIHNldHdkKGlucHV0X2RhdGFfd2QpDQoNCmRhdGFfZmlsZSA8LSAibGFiY2hhcnQtc2xvcGUtZGF0YS54bHN4Ig0KDQojIA0KIyAjIEdldCB0aGUgbmFtZXMgb2YgYWxsIHNoZWV0cyBpbiB0aGUgRXhjZWwgZmlsZQ0Kc2hlZXRfbmFtZXMgPC0gcmVhZHhsOjpleGNlbF9zaGVldHMoZGF0YV9maWxlKQ0KYWxsX3RyaWFsc19zZWxlY3QgPC0gYygic3RhcnRfZGF0ZSIsICJvcmRlciIsICJwaGFzZSIsICJjeWNsZSIsICJkYXRlIiwgInRpbWUiKQ0Kc2xvcGVfbGlzdCA8LSBsaXN0KCkNCg0KZm9yIChzaGVldCBpbiBzaGVldF9uYW1lcykgew0KDQogIGRmIDwtIHJlYWRfZXhjZWwoZGF0YV9maWxlLCBzaGVldCA9IHNoZWV0KSAlPiUgDQogIGRwbHlyOjpyZW5hbWVfd2l0aCh0b2xvd2VyKQ0KICANCmFfbmFtZSA8LSBwYXN0ZTAoImFfIiwgdG9sb3dlcihzaGVldCkpDQphX2RmIDwtIGRmICU+JQ0KICBkcGx5cjo6c2VsZWN0KHN0YXJ0c193aXRoKCdhJyksIGFsbF90cmlhbHNfc2VsZWN0KSAlPiUgDQogIGRwbHlyOjpyZW5hbWUodGVtcCA9IGFfdGVtcCkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKGFjcm9zcyhzdGFydHNfd2l0aCgnYScpLCBhcy5udW1lcmljKSkgJT4lIA0KICBwaXZvdF9sb25nZXIoDQogICAgY29scyA9IHN0YXJ0c193aXRoKCdhJyksICMgU2VsZWN0IGFsbCBjb2x1bW5zIHRvIHBpdm90DQogICAgbmFtZXNfdG8gPSBjKCJjaGFtYmVyX2lkIiwgIi52YWx1ZSIpLCAjIFNlcGFyYXRlIGNvbHVtbiBuYW1lcyBpbnRvICdpZCcgYW5kIG90aGVyIHZhcmlhYmxlcw0KICAgIG5hbWVzX3NlcCA9ICJfIg0KICApICU+JQ0KICBkcGx5cjo6bXV0YXRlKHJlc3Bpcm9tZXRlcl9ncm91cCA9ICJhIikgIyBBZGQgYSBuZXcgY29sdW1uIHdpdGggYSBmaXhlZCB2YWx1ZQ0KDQpzbG9wZV9saXN0W1thX25hbWVdXTwtIGFfZGYNCg0KYl9uYW1lIDwtIHBhc3RlMCgiYl8iLCB0b2xvd2VyKHNoZWV0KSkNCmJfZGYgPC0gZGYgJT4lIA0KICBkcGx5cjo6c2VsZWN0KHN0YXJ0c193aXRoKCdiJyksIGFsbF90cmlhbHNfc2VsZWN0KSAlPiUgDQogIGRwbHlyOjpyZW5hbWUodGVtcCA9IGJfdGVtcCkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKGFjcm9zcyhzdGFydHNfd2l0aCgnYicpLCBhcy5udW1lcmljKSkgJT4lIA0KICBwaXZvdF9sb25nZXIoDQogICAgY29scyA9IHN0YXJ0c193aXRoKCdiJyksICMgU2VsZWN0IGFsbCBjb2x1bW5zIHRvIHBpdm90DQogICAgbmFtZXNfdG8gPSBjKCJjaGFtYmVyX2lkIiwgIi52YWx1ZSIpLCAjIFNlcGFyYXRlIGNvbHVtbiBuYW1lcyBpbnRvICdpZCcgYW5kIG90aGVyIHZhcmlhYmxlcw0KICAgIG5hbWVzX3NlcCA9ICJfIg0KICApICU+JSANCiAgICBkcGx5cjo6bXV0YXRlKHJlc3Bpcm9tZXRlcl9ncm91cCA9ICJiIikNCg0Kc2xvcGVfbGlzdFtbYl9uYW1lXV0gPC0gYl9kZg0KDQpjX25hbWUgPC0gcGFzdGUwKCJjXyIsIHRvbG93ZXIoc2hlZXQpKQ0KY19kZiA8LSBkZiAlPiUgDQogIGRwbHlyOjpzZWxlY3Qoc3RhcnRzX3dpdGgoJ2MnKSwgYWxsX3RyaWFsc19zZWxlY3QpICU+JSANCiAgZHBseXI6OnJlbmFtZSh0ZW1wID0gY190ZW1wLA0KICAgICAgICAgICAgICAgIGlfY3ljbGUgPSBjeWNsZSkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKGFjcm9zcyhzdGFydHNfd2l0aCgnYycpLCBhcy5udW1lcmljKSkgJT4lDQogIHBpdm90X2xvbmdlcigNCiAgICBjb2xzID0gc3RhcnRzX3dpdGgoJ2MnKSwgIyBTZWxlY3QgYWxsIGNvbHVtbnMgdG8gcGl2b3QNCiAgICBuYW1lc190byA9IGMoImNoYW1iZXJfaWQiLCAiLnZhbHVlIiksICMgU2VwYXJhdGUgY29sdW1uIG5hbWVzIGludG8gJ2lkJyBhbmQgb3RoZXIgdmFyaWFibGVzDQogICAgbmFtZXNfc2VwID0gIl8iDQogICkgJT4lIA0KICAgIGRwbHlyOjptdXRhdGUocmVzcGlyb21ldGVyX2dyb3VwID0gImMiKSAlPiUgDQogIGRwbHlyOjpyZW5hbWUoY3ljbGUgPSBpX2N5Y2xlKQ0KDQpzbG9wZV9saXN0W1tjX25hbWVdXSA8LSBjX2RmDQoNCmRfbmFtZSA8LSBwYXN0ZTAoImRfIiwgdG9sb3dlcihzaGVldCkpDQpkX2RmIDwtIGRmICU+JSANCiAgZHBseXI6OnNlbGVjdChzdGFydHNfd2l0aCgnZCcpLCBhbGxfdHJpYWxzX3NlbGVjdCkgJT4lIA0KICBkcGx5cjo6cmVuYW1lKHRlbXAgPSBkX3RlbXAsDQogICAgICAgICAgICAgICAgaV9kYXRlID0gZGF0ZSkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKGFjcm9zcyhzdGFydHNfd2l0aCgnZCcpLCBhcy5udW1lcmljKSkgJT4lDQogIHBpdm90X2xvbmdlcigNCiAgICBjb2xzID0gc3RhcnRzX3dpdGgoJ2QnKSwgIyBTZWxlY3QgYWxsIGNvbHVtbnMgdG8gcGl2b3QNCiAgICBuYW1lc190byA9IGMoImNoYW1iZXJfaWQiLCAiLnZhbHVlIiksICMgU2VwYXJhdGUgY29sdW1uIG5hbWVzIGludG8gJ2lkJyBhbmQgb3RoZXIgdmFyaWFibGVzDQogICAgbmFtZXNfc2VwID0gIl8iDQogICkgJT4lIA0KICAgIGRwbHlyOjptdXRhdGUocmVzcGlyb21ldGVyX2dyb3VwID0gImQiKSAlPiUgDQogIGRwbHlyOjpyZW5hbWUoZGF0ZSA9IGlfZGF0ZSkNCg0Kc2xvcGVfbGlzdFtbZF9uYW1lXV0gPC0gZF9kZg0KfQ0KDQoNCnNsb3BlX2RmIDwtIGJpbmRfcm93cyhzbG9wZV9saXN0KSAlPiUgDQogIGRwbHlyOjptdXRhdGUocmVzcF9jYXRfZGF0ZSA9IHBhc3RlMChyZXNwaXJvbWV0ZXJfZ3JvdXAsICJfIiwgc3RhcnRfZGF0ZSksDQogICAgICAgICAgICAgICAgY2hhbWJlcl9uID0gc3RyX2V4dHJhY3QoY2hhbWJlcl9pZCwgIlxcZCsiKSwNCiAgICAgICAgICAgICAgICBpZF9wcm94ID0gcGFzdGUwKHJlc3BfY2F0X2RhdGUsICJfIiwgY2hhbWJlcl9uKSwNCiAgICAgICAgICAgICAgICB0aW1lX2htcyA9IGFzX2htcyh0aW1lKjM2MDApLA0KICAgICAgICAgICAgICAgIGRhdGVfY2hyID0gZm9ybWF0KGRhdGUsICIlZC8lbS8lWSIpDQogICAgICAgICAgICAgICAgKQ0KYGBgDQoNCiMjIEZpc2ggbWV0YWRhdGENCg0KKirwn5K/IG1ldGFkYXRhKio6IFRoaXMgaXMgdGhlIG1ldGEgZGF0YSBmb3IgZWFjaCBjaGFtYmVyDQoNCipOb3RlOiBXZSBhcmUgYWxzbyBhZGRpbmcgdm9sdW1lIGJhc2VkIG9uIGNoYW1iZXIgdHlwZS4qDQoNCmBgYHtyfQ0Kc2V0d2QoaW5wdXRfZGF0YV93ZCkNCg0KbWV0YWRhdGEgPC0gcmVhZF9leGNlbCgiZmlzaC1tZXRhLnhsc3giLCBuYSA9ICJOQSIpICU+JSANCiAgZHBseXI6Om11dGF0ZShpZF9zcGxpdCA9IGlkKSAlPiUgDQogIHRpZHlyOjpzZXBhcmF0ZShpZF9zcGxpdCwgaW50byA9IGMoInJlc3Bpcm9tZXRlcl9ncm91cCIsICJzYWxpbml0eV9ncm91cCIsICJzdGFydF9kYXRlIiwgImNoYW1iZXIiKSwgc2VwID0gIl8iKSAlPiUgDQogIGRwbHlyOjptdXRhdGUoDQogICAgICB2b2x1bWUgPSBkcGx5cjo6Y2FzZV93aGVuKA0KICAgICAgICBjaGFtYmVyX3R5cGUgPT0gIkwiIH4gMC4zMDAsDQogICAgICAgIGNoYW1iZXJfdHlwZSA9PSAiTV9NIiB+IDAuMTA1LA0KICAgICAgICBjaGFtYmVyX3R5cGUgPT0gIk1fTk0iIH4gMC4xMSwNCiAgICAgICAgY2hhbWJlcl90eXBlID09ICJTIiB+IDAuMDU4LA0KICAgICAgICBjaGFtYmVyX3R5cGUgPT0gIlNNIiB+IDAuMDc1LA0KICAgICAgICBjaGFtYmVyX3R5cGUgPT0gIkQzIiB+IDAuMDU1LA0KICAgICAgICBUUlVFIH4gTkENCiAgICAgICksDQogICAgICBpZF9wcm94ID0gcGFzdGUwKHJlc3Bpcm9tZXRlcl9ncm91cCwgIl8iLCBzdGFydF9kYXRlLCAiXyIsIGNoYW1iZXIpLA0KICAgICAgcmVsX3NpemUgPSBtYXNzL3ZvbHVtZSkNCmBgYA0KDQojIyBVcmJpbmEsIEdsb3ZlciwgYW5kIEZvcnN0ZXIgKDIwMTIpDQoNCioq8J+SvyB1cmJpbmFfZXRfYWxfMjAxMioqOiBUaGlzIGlzIHRoZSBtZWFuIGxldmVsIGRhdGEgZXh0cmFjdGVkIGZyb20gVXJiaW5hLCBHbG92ZXIsIGFuZCBGb3JzdGVyICgyMDEyKV5bMl1eIEZpZ3VyZSAxYS4gV2UgdXNlZCB0aGUgbWV0YURpZ2l0aXNlIHBhY2thZ2UgaW4gUiB0byBleHRyYWN0IHRoZSBkYXRhIF5bM11eLg0KDQpgYGB7cn0NCnNldHdkKGlucHV0X2RhdGFfd2QpDQoNCnVyYmluYV9ldF9hbF8yMDEyIDwtIHJlYWRfZXhjZWwoInVyYmluYS1ldC1hbC0yMDEyLWZpZzFhLnhsc3giKQ0KYGBgDQoNCiMjIE/igoJjcml0IHZpdXNhbCBpbnNwZWN0aW9uDQoNCioq8J+SvyBvMmNyaXRfY2hlY2sqKjogVGhpcyBkYXRhIGZyYW1lIGluY2x1ZGVzIHRoZSB2aXN1YWwgYmFzZWQgYXNzZXNzbWVudCBmb3IgT+KCgmNyaXQgZm9yIGFsbCBmaXNoIGluY2x1ZGVkIGluIHRoZSBhbmFseXNpcyAoKm4qID0gNTgpLiBUaGUgaW5zcGVjdGlvbnMgd2VyZSBtYWRlIHVzaW5nIGZpZ3VyZXMgZ2VuYnJhdGVkIGJ5IHRoZSBgcGxvdE8yY3JpdCgpYCBmdW5jdGlvbiwgYW5kIGNhbiBiZSB2aWV3ZWQgaW4gYGNvbWJpbmVkX2NoYWJvdF9wbG90cy5wZGZgLiBUaGUgdmlzdWFsIGFzc2Vzc21lbnQgd2FzIGRvbmUgaW5kZXBlbmRlbnRseSBieSBhbGwgYXV0aG9ycywgYW5kIHRoZSBwcmVzZW5jZSBvZiBhbiBP4oKCY3JpdHMgYWxsb2NhdGVkIHRvICd5ZXMnLCAnbm8nLCAnbWF5YmUnLiBJZiB5ZXMsIG9yIG1heWJlLCBhbiBlc3RpbWF0ZSBvZiB0aGUgZGlzc29sdmVkIG94eWdlbiBwZXJjZW50YWdlIHdhcyBnaXZlbi4gDQoNCkRpcmVjdG9yeSB0byB0aGUgZmlndXJlcyAgIA0KDQrwn5OBIGdtYWMtbW8yLTI0Lw0K4pSU4pSA4pSAIPCfk4Igb3V0cHV0LWZpZy8gIA0KICAgIOKUlOKUgOKUgCDwn5OCIG1vZGVsX2NoYWJvdC8gDQogICAgICAgICDilJTilIDilIAg8J+ThCBjb21iaW5lZF9jaGFib3RfcGxvdHMucGRmICAgDQoNCmBgYHtyfQ0Kc2V0d2QoaW5wdXRfZGF0YV93ZCkNCg0KbzJjcml0X2NoZWNrIDwtIHJlYWRfZXhjZWwoIm8yY3JpdC12aXN1YWwtYXNzZXNzbWVudC54bHN4IiwgbmEgPSAiTkEiKQ0KYGBgDQoNCiMjIyBDb21iaW5kaW5nIG1ldGFkYXRhDQoNCkFkZGluZyB0aGUgbWV0YSBkYXRhIHRvIHRoZSBzbG9wZXMgZGF0YSBmcmFtZQ0KDQpgYGB7cn0NCnNsb3BlX2RmXzIgPC0gc2xvcGVfZGYgJT4lIA0KICBkcGx5cjo6c2VsZWN0KC1zdGFydF9kYXRlLCAtcmVzcGlyb21ldGVyX2dyb3VwKSAlPiUgDQogIGxlZnRfam9pbihtZXRhZGF0YSwgYnkgPSAiaWRfcHJveCIpICU+JSANCiAgZHBseXI6Om11dGF0ZShsaWdodF9kYXJrID0gaWZfZWxzZSh0aW1lX2htcyA+PSBhcy5obXMoIjA3OjAwOjAwIikgJiB0aW1lX2htcyA8IGFzLmhtcygiMTk6MDA6MDAiKSwgImxpZ2h0IiwgImRhcmsiKSkgJT4lIA0KICBkcGx5cjo6YXJyYW5nZShpZCkNCmBgYA0KDQo8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+DQoNCiMg8J+nuSBEYXRhIHRpZHkNCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQojIyBOdW1iZXJzDQoNCldlIGhhdmUgKio2NCBmaXNoKiogd2l0aCBNT+KCgiBkYXRhDQoNCmBgYHtyfQ0KbiA8LSBzbG9wZV9kZl8yICU+JSANCiAgZHBseXI6OmZpbHRlcihjaGFtYmVyX2NvbmRpdGlvbiA9PSAiZmlzaCIpICU+JSANCiAgZHBseXI6OmRpc3RpbmN0KGlkKSAlPiUgDQogIG5yb3coLikNCg0KcGFzdGUwKCJuID0gIiwgbikNCmBgYA0KDQpXaXRoIDQ4IGZyb20gdGhlIDAgcHB0IGFuZCA0OCBmcm9tIDkgcHB0IGdyb3Vwcw0KDQpgYGB7cn0NCnNsb3BlX2RmXzIgJT4lIA0KICBkcGx5cjo6ZmlsdGVyKGNoYW1iZXJfY29uZGl0aW9uID09ICJmaXNoIikgJT4lDQogIGRwbHlyOjpncm91cF9ieShzYWxpbml0eV9ncm91cCkgJT4lIA0KICBkcGx5cjo6cmVmcmFtZSgnbiB0b3RhbCcgPSBsZW5ndGgodW5pcXVlKGlkKSkpICU+JSANCiAgZ3QoKSAlPiUgDQogIGNvbHNfbGFiZWwoDQogICAgc2FsaW5pdHlfZ3JvdXAgPSAiU2FsaW5pdHkgZ3JvdXAiDQogICkgJT4lIA0KICBjb2xzX2FsaWduKA0KICAgIGFsaWduID0gImNlbnRlciIsIA0KICAgIGNvbHVtbnMgPSBldmVyeXRoaW5nKCkNCiAgKQ0KYGBgDQoNCiMjIEZpc2ggc2l6ZQ0KDQpIZXJlIHdlIGNhbGN1bGF0ZSB0aGUgbWVhbiBsZW5ndGggYW5kIHNpemUgb2YgZmlzaCB1c2VkIGluIHRoZSBleHBlcmltZW50Lg0KDQpgYGB7cn0NCm1hc3NfbGVuZ3RoIDwtIHNsb3BlX2RmXzIgJT4lIA0KICBkcGx5cjo6ZmlsdGVyKGNoYW1iZXJfY29uZGl0aW9uID09ICJmaXNoIikgJT4lDQogIGRwbHlyOjpncm91cF9ieShpZCkgJT4lIA0KICBkcGx5cjo6c2FtcGxlX24oMSkgJT4lIA0KICBkcGx5cjo6dW5ncm91cCgpICU+JSANCiAgZHBseXI6OnJlZnJhbWUoeF9tYXNzID0gcm91bmQobWVhbihtYXNzLCBuYS5ybSA9IFRSVUUpLCAzKSwNCiAgICAgICAgICAgICAgICAgbWluX21hc3MgPSByb3VuZChtaW4obWFzcywgbmEucm0gPSBUUlVFKSwgMyksDQogICAgICAgICAgICAgICAgIG1heF9tYXNzID0gcm91bmQobWF4KG1hc3MsIG5hLnJtID0gVFJVRSksIDMpLA0KICAgICAgICAgICAgICAgICB4X2xlbmd0aCA9IHJvdW5kKG1lYW4obGVuZ3RoLCBuYS5ybSA9IFRSVUUpLCAyKSwNCiAgICAgICAgICAgICAgICAgbWluX2xlbmd0aCA9IHJvdW5kKG1pbihsZW5ndGgsIG5hLnJtID0gVFJVRSksIDIpLA0KICAgICAgICAgICAgICAgICBtYXhfbGVuZ3RoID0gcm91bmQobWF4KGxlbmd0aCwgbmEucm0gPSBUUlVFKSwgMikpDQoNCm1hc3NfbWVhbiA8LSBtYXNzX2xlbmd0aCAlPiUgDQogIHB1bGwoeF9tYXNzKQ0KDQptYXNzX21pbiA8LSBtYXNzX2xlbmd0aCAlPiUgDQogIHB1bGwobWluX21hc3MpDQoNCm1hc3NfbWF4IDwtIG1hc3NfbGVuZ3RoICU+JSANCiAgcHVsbChtYXhfbWFzcykNCg0KbGVuZ3RoX21lYW4gPC0gbWFzc19sZW5ndGggJT4lIA0KICBwdWxsKHhfbGVuZ3RoKQ0KDQpsZW5ndGhfbWluIDwtIG1hc3NfbGVuZ3RoICU+JSANCiAgcHVsbChtaW5fbGVuZ3RoKQ0KDQpsZW5ndGhfbWF4IDwtIG1hc3NfbGVuZ3RoICU+JSANCiAgcHVsbChtYXhfbGVuZ3RoKQ0KDQpwYXN0ZTAoIlRoZSBtZWFuIG1hc3Mgb2YgZmlzaCB3YXMgIiwgbWFzc19tZWFuLCAiIGcgKHJhbmdlOiAiLCBtYXNzX21pbiwgIi0iLCBtYXNzX21heCwgIikiLA0KICAgICAgICIsIGFuZCB0aGUgbWVhbiBsZW5ndGggd2FzICIsIGxlbmd0aF9tZWFuLCAiIG1tIChyYW5nZTogIiwgbGVuZ3RoX21pbiwgIi0iLCBsZW5ndGhfbWF4LCAiKSIpDQpgYGANCg0KIyMgRmlsdGVyaW5nIHRyaWFscw0KDQpXZSB3aWxsIHJlbW92ZSA2IHRyaWFscyB3aGljaCBoYWQgZXJyb3JzLiBUaGVzZSBhcmUgYXMgZm9sbG93czoNCg0KLSAgIGFfMF8yNW5vdl8zIGZpc2ggZGllZCBkdXJpbmcgdHJpYWwNCi0gICBiXzBfMjZub3ZfNCBmbGF0IGxpbmVkIGVhcmx5DQotICAgY18wXzIybm92XzIgY2hhbWJlciB3YXMgb3BlbmVkIGVhcmx5DQotICAgY185XzI2bm92XzIgY2hhbWJlciB3YXMgb3BlbmVkIGVhcmx5DQotICAgY185XzI2bm92XzQgY2hhbWJlciB3YXMgb3BlbmVkIGVhcmx5DQotICAgZF85XzI3bm92XzMgc2Vuc29yIHdhcyBqdW1weSBhbmQgZW5kIHBvaW50cyB3ZXJlIGhhcmQgdG8gY29uZmlkZW50bHkgSUQgdmlzdWFsbHkNCg0KYGBge3J9DQpyZW1vdmVfdHJpYWxfZXJyb3IgPC0gYygiYV8wXzI1bm92XzMiLCAiYl8wXzI2bm92XzQiLCAiY18wXzIybm92XzIiLCAiY185XzI2bm92XzIiLCAiY185XzI2bm92XzQiLCAiZF85XzI3bm92XzMiKQ0KDQpzbG9wZV9kZl9maWx0ZXIgPC0gc2xvcGVfZGZfMiAlPiUgDQogIGRwbHlyOjpmaWx0ZXIoIShpZCAlaW4lIHJlbW92ZV90cmlhbF9lcnJvcikpDQpgYGANCg0KV2Ugbm93IGhhdmUgKio1OCBmaXNoKiogd2l0aCBNTzIgZGF0YQ0KDQpgYGB7cn0NCm4gPC0gc2xvcGVfZGZfZmlsdGVyICU+JSANCiAgZHBseXI6OmZpbHRlcihjaGFtYmVyX2NvbmRpdGlvbiA9PSAiZmlzaCIpICU+JSANCiAgZHBseXI6OmRpc3RpbmN0KGlkKSAlPiUgDQogIG5yb3coLikNCg0KcGFzdGUwKCJuID0gIiwgbikNCmBgYA0KDQpXaXRoIDMwIGluIHRoZSAwIHBwdCBncm91cCBhbmQgMjggaW4gdGhlIDkgcHB0IGdyb3VwDQoNCmBgYHtyfQ0Kc2xvcGVfZGZfZmlsdGVyICU+JSANCiAgZHBseXI6OmZpbHRlcihjaGFtYmVyX2NvbmRpdGlvbiA9PSAiZmlzaCIpICU+JQ0KICBkcGx5cjo6Z3JvdXBfYnkoc2FsaW5pdHlfZ3JvdXApICU+JSANCiAgZHBseXI6OnJlZnJhbWUoJ24gdG90YWwnID0gbGVuZ3RoKHVuaXF1ZShpZCkpKSAlPiUgDQogIGd0KCkgJT4lIA0KICBjb2xzX2xhYmVsKA0KICAgIHNhbGluaXR5X2dyb3VwID0gIlNhbGluaXR5IGdyb3VwIg0KICApICU+JSANCiAgY29sc19hbGlnbigNCiAgICBhbGlnbiA9ICJjZW50ZXIiLCANCiAgICBjb2x1bW5zID0gZXZlcnl0aGluZygpDQogICkNCmBgYA0KDQpNYXNzIGFuZCBzaXplIG9mIGZpc2ggYWZ0ZXIgcmVtb3ZpbmcgNiB0cmlhbHMgd2hpY2ggaGFkIGVycm9ycw0KDQpgYGB7cn0NCm1hc3NfbGVuZ3RoIDwtIHNsb3BlX2RmX2ZpbHRlciAlPiUgDQogIGRwbHlyOjpmaWx0ZXIoY2hhbWJlcl9jb25kaXRpb24gPT0gImZpc2giKSAlPiUNCiAgZHBseXI6Omdyb3VwX2J5KGlkKSAlPiUgDQogIGRwbHlyOjpzYW1wbGVfbigxKSAlPiUgDQogIGRwbHlyOjp1bmdyb3VwKCkgJT4lIA0KICBkcGx5cjo6cmVmcmFtZSh4X21hc3MgPSByb3VuZChtZWFuKG1hc3MsIG5hLnJtID0gVFJVRSksIDMpLA0KICAgICAgICAgICAgICAgICBtaW5fbWFzcyA9IHJvdW5kKG1pbihtYXNzLCBuYS5ybSA9IFRSVUUpLCAzKSwNCiAgICAgICAgICAgICAgICAgbWF4X21hc3MgPSByb3VuZChtYXgobWFzcywgbmEucm0gPSBUUlVFKSwgMyksDQogICAgICAgICAgICAgICAgIHhfbGVuZ3RoID0gcm91bmQobWVhbihsZW5ndGgsIG5hLnJtID0gVFJVRSksIDIpLA0KICAgICAgICAgICAgICAgICBtaW5fbGVuZ3RoID0gcm91bmQobWluKGxlbmd0aCwgbmEucm0gPSBUUlVFKSwgMiksDQogICAgICAgICAgICAgICAgIG1heF9sZW5ndGggPSByb3VuZChtYXgobGVuZ3RoLCBuYS5ybSA9IFRSVUUpLCAyKSkNCg0KbWFzc19tZWFuIDwtIG1hc3NfbGVuZ3RoICU+JSANCiAgcHVsbCh4X21hc3MpDQoNCm1hc3NfbWluIDwtIG1hc3NfbGVuZ3RoICU+JSANCiAgcHVsbChtaW5fbWFzcykNCg0KbWFzc19tYXggPC0gbWFzc19sZW5ndGggJT4lIA0KICBwdWxsKG1heF9tYXNzKQ0KDQpsZW5ndGhfbWVhbiA8LSBtYXNzX2xlbmd0aCAlPiUgDQogIHB1bGwoeF9sZW5ndGgpDQoNCmxlbmd0aF9taW4gPC0gbWFzc19sZW5ndGggJT4lIA0KICBwdWxsKG1pbl9sZW5ndGgpDQoNCmxlbmd0aF9tYXggPC0gbWFzc19sZW5ndGggJT4lIA0KICBwdWxsKG1heF9sZW5ndGgpDQoNCnBhc3RlMCgiVGhlIG1lYW4gbWFzcyBvZiBmaXNoIHdhcyAiLCBtYXNzX21lYW4sICIgZyAocmFuZ2U6ICIsIG1hc3NfbWluLCAiLSIsIG1hc3NfbWF4LCAiKSIsDQogICAgICAgIiwgYW5kIHRoZSBtZWFuIGxlbmd0aCB3YXMgIiwgbGVuZ3RoX21lYW4sICIgbW0gKHJhbmdlOiAiLCBsZW5ndGhfbWluLCAiLSIsIGxlbmd0aF9tYXgsICIpIikNCmBgYA0KDQpDaGFtYmVyIHNpemUgYnJlYWtkb3duDQoNCmBgYHtyfQ0Kc2xvcGVfZGZfZmlsdGVyICU+JSANCiAgZHBseXI6OmZpbHRlcihjaGFtYmVyX2NvbmRpdGlvbiA9PSAiZmlzaCIpICU+JQ0KICBkcGx5cjo6bXV0YXRlKHZvbHVtZSA9IGlmX2Vsc2Uodm9sdW1lID09IDAuMDU1LCAwLjA1OCwgdm9sdW1lKSkgJT4lIA0KICBkcGx5cjo6Z3JvdXBfYnkodm9sdW1lKSAlPiUgDQogIGRwbHlyOjpyZWZyYW1lKCduIHRvdGFsJyA9IGxlbmd0aCh1bmlxdWUoaWQpKSwNCiAgICAgICAgICAgICAgICAgbWVkaWFuX21hc3MgPSBtZWRpYW4obWFzcywgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgICAgICAgc2RfbWFzcyA9IHNkKG1hc3MsIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ3QoKSAlPiUgDQogIGNvbHNfbGFiZWwoDQogICAgdm9sdW1lID0gIkNoYW1iZXIgdHlwZSIsDQogICAgbWVkaWFuX21hc3MgPSAiTWVkaWFuIG1hc3MiLA0KICAgIHNkX21hc3MgPSAiU3RhbmRhcmQgZGV2aWF0aW9uIG1hc3MiDQogICkgJT4lIA0KICBjb2xzX2FsaWduKA0KICAgIGFsaWduID0gImNlbnRlciIsIA0KICAgIGNvbHVtbnMgPSBldmVyeXRoaW5nKCkNCiAgKQ0KYGBgDQoNCk51bWJlcnMgcGVyIHRyaWFsIGFwcHJvYWNoDQoNCmBgYHtyfQ0KcGhhc2VzIDwtIGMoIjUwYyIsICIxMDBjIikNCg0Kc2xvcGVfZGZfZmlsdGVyICU+JSANCiAgZHBseXI6OmZpbHRlcihjaGFtYmVyX2NvbmRpdGlvbiA9PSAiZmlzaCIgJiBwaGFzZSAlaW4lIHBoYXNlcykgJT4lDQogIGRwbHlyOjpncm91cF9ieShwaGFzZSkgJT4lIA0KICBkcGx5cjo6cmVmcmFtZSgnbiB0b3RhbCcgPSBsZW5ndGgodW5pcXVlKGlkKSkpICU+JSANCiAgZ3QoKSAlPiUgDQogIGNvbHNfbGFiZWwoDQogICAgcGhhc2UgPSAiVHlwZSBvZiB0cmlhbCIsDQogICkgJT4lIA0KICBjb2xzX2FsaWduKA0KICAgIGFsaWduID0gImNlbnRlciIsIA0KICAgIGNvbHVtbnMgPSBldmVyeXRoaW5nKCkNCiAgKQ0KYGBgDQoNCiMjIEZpbHRlcmluZyBNT+KCgiBlc3RpbWF0ZXMNCg0KSGVyZSB3ZSBhcHBseSB0aGUgZm9sbG93aW5nIGZpbHRlcnMgdG8gdGhlIE1P4oKCIGRhdGE6DQoNCi0gICBSZW1vdmUgdGhlIGZpcnN0IDUgU01SIGN5Y2xlcyAoYnVybiBpbikNCi0gICBSZW1vdmUgYWxsIHBvc2l0aXZlIHJhdyBzbG9wZXMNCi0gICBSZW1vdmUgYWxsIE1P4oKCIGNhbGN1bGF0ZWQgdXNpbmcgbGVzcyB0aGVuIDYwIGRhdGEgcG9pbnRzICg1IG1pbiBhdCAwLjIgSHopDQotICAgUmVtb3ZlIGFsbCBNT+KCgiBjYWxjdWxhdGVkIGlmIE/igoIgaW5jcmVhc2VzIGluIGEgY2xvc2VkIHBoYXNlIChpLmUuIHRyaWFsIGhhcyBlbmRlZCkNCg0KQ2hlY2sgcG9zaXRpdmUgdmFsdWVzIGZvciBNT+KCgiBiZWZvcmUgcmVtb3ZpbmcuDQoNCmBgYHtyfQ0Kc2xvcGVfdGlkeV9yZW1vdmVfZmx1c2ggPC0gc2xvcGVfZGZfZmlsdGVyICU+JQ0KICBkcGx5cjo6ZmlsdGVyKHBoYXNlICE9ICJzbXIiLCBjaGFtYmVyX2NvbmRpdGlvbiA9PSAiZmlzaCIpICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KGlkKSAlPiUNCiAgZHBseXI6OmFycmFuZ2UoaWQsIG9yZGVyKSAlPiUgICMgRW5zdXJlIHRoZSBkYXRhIGlzIHNvcnRlZCB3aXRoaW4gZWFjaCBncm91cA0KICBkcGx5cjo6bXV0YXRlKG8yX2RpZmYgPSBpZl9lbHNlKHJvd19udW1iZXIoKSA9PSAxLCAwLCBvMiAtIGxhZyhvMikpLCAjIENhbGN1bGF0ZSB0aGUgZGlmZmVyZW5jZSBpbiAnbzInDQogICAgICAgICAgICAgICAgbzJfZGlmZl9jdW1zdW0gPSBjdW1zdW0obzJfZGlmZiA+IDEpKSAlPiUgICMgQ2hlY2tzIGZpcnN0IG9jY3VycmVuY2UgYW5kIHN1bXMgDQogIGRwbHlyOjpmaWx0ZXIobzJfZGlmZl9jdW1zdW0gPT0gMCkgJT4lICAjIEtlZXAgcm93cyB1bnRpbCB0aGUgZmlyc3QganVtcCA+IDENCiAgZHBseXI6OnVuZ3JvdXAoKSAlPiUNCiAgZHBseXI6OnNlbGVjdCgtbzJfZGlmZiwgLW8yX2RpZmZfY3Vtc3VtKQ0KDQpwb3N0aXZlX3Nsb3BlcyA8LSBzbG9wZV90aWR5X3JlbW92ZV9mbHVzaCAlPiUNCiAgZHBseXI6OmZpbHRlcihjaGFtYmVyX2NvbmRpdGlvbiA9PSAiZmlzaCIgJiBtbzJjb3JyID4gMCkNCg0Kbl9wb3N0aXZlX3Nsb3BlcyA8LSBucm93KHBvc3RpdmVfc2xvcGVzKQ0KDQpuX3Nsb3BlcyA8LSAgbnJvdyhzbG9wZV90aWR5X3JlbW92ZV9mbHVzaCkNCg0KbGlzdF9wb3N0aXZlX2FsbCA8LSBwb3N0aXZlX3Nsb3BlcyAlPiUgDQogIGRwbHlyOjpkaXN0aW5jdChpZCkgJT4lIA0KICBkcGx5cjo6cHVsbChpZCkNCg0KcHJpbnQocGFzdGUwKCJUaGVyZSBhcmUgIiwgbGVuZ3RoKGxpc3RfcG9zdGl2ZV9hbGwpLCAiIGZpc2ggd2l0aCBwb3N0aXZlIHNsb3Blcy4gVGhlc2UgZmlzaCBhcmU6ICIsIHBhc3RlKGxpc3RfcG9zdGl2ZV9hbGwsIGNvbGxhcHNlID0gIiwgIiksICIuIEZvciBhbGwgZXN0aW1hdGVkIHNsb3BlcyAobiA9ICIsIG5fc2xvcGVzLCAiKSAiLCByb3VuZCgobl9wb3N0aXZlX3Nsb3Blcy9uX3Nsb3BlcykqMTAwLDIpICwgIiUgd2VyZSBwb3N0aXZlIChuID0gIiwgbl9wb3N0aXZlX3Nsb3BlcywgIikiKSkNCmBgYA0KDQpGaWx0ZXJpbmcgdGhlIE1P4oKCIGRhdGENCg0KYGBge3J9DQpjeWNsZV9idXJuIDwtIDA6NA0KDQpzbG9wZV9kZl9maWx0ZXJfMSA8LSBzbG9wZV9kZl9maWx0ZXIgJT4lDQogIGRwbHlyOjpmaWx0ZXIoIShjeWNsZSAlaW4lIGN5Y2xlX2J1cm4pICYgDQogICAgICAgICAgICAgICAgICBtbzJjb3JyIDwgMCAmIA0KICAgICAgICAgICAgICAgICAgbiA+IDYwICYNCiAgICAgICAgICAgICAgICAgIGNoYW1iZXJfY29uZGl0aW9uID09ICJmaXNoIg0KICAgICAgICAgICAgICAgICkNCiAgDQojIEZpbHRlciBvdXQgdGhlIGVuZCBmbHVzaA0Kc2xvcGVfdGlkeV9jbG9zZWQgPC0gc2xvcGVfZGZfZmlsdGVyXzEgJT4lDQogIGRwbHlyOjpmaWx0ZXIocGhhc2UgIT0gInNtciIpICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KGlkKSAlPiUNCiAgZHBseXI6OmFycmFuZ2UoaWQsIG9yZGVyKSAlPiUgICMgRW5zdXJlIHRoZSBkYXRhIGlzIHNvcnRlZCB3aXRoaW4gZWFjaCBncm91cA0KICBkcGx5cjo6bXV0YXRlKG8yX2RpZmYgPSBpZl9lbHNlKHJvd19udW1iZXIoKSA9PSAxLCAwLCBvMiAtIGxhZyhvMikpLCAjIENhbGN1bGF0ZSB0aGUgZGlmZmVyZW5jZSBpbiAnbzInDQogICAgICAgICAgICAgICAgbzJfZGlmZl9jdW1zdW0gPSBjdW1zdW0obzJfZGlmZiA+IDEpKSAlPiUgICMgQ2hlY2tzIGZpcnN0IG9jY3VycmVuY2UgYW5kIHN1bXMgDQogIGRwbHlyOjpmaWx0ZXIobzJfZGlmZl9jdW1zdW0gPT0gMCkgJT4lICAjIEtlZXAgcm93cyB1bnRpbCB0aGUgZmlyc3QganVtcCA+IDENCiAgZHBseXI6OnVuZ3JvdXAoKSAlPiUNCiAgZHBseXI6OnNlbGVjdCgtbzJfZGlmZiwgLW8yX2RpZmZfY3Vtc3VtKQ0KDQpzbG9wZV90aWR5X3NtciA8LSBzbG9wZV9kZl9maWx0ZXJfMSAlPiUgDQogIGRwbHlyOjpmaWx0ZXIocGhhc2UgPT0gInNtciIpDQoNCnNsb3BlX2RmX2ZpbHRlcl8yIDwtIHJiaW5kKHNsb3BlX3RpZHlfc21yLCBzbG9wZV90aWR5X2Nsb3NlZCkgJT4lIA0KICBkcGx5cjo6YXJyYW5nZShpZCwgb3JkZXIpDQpgYGANCg0KIyMgQ2FsY3VsYXRpbmcgU01SDQoNCldlIHdpbGwgY2FsY3VsYXRlIFNNUiB1c2luZyBgY2FsY1NNUmAgZnVuY3Rpb24gYnkgQ2hhYm90LCBTdGVmZmVuc2VuIGFuZCBGYXJyZWxsICgyMDE2KV5bMV1eLiBTcGVjaWZpY2FsbHksIHdlIHVzZSBtZWFuIG9mIHRoZSBsb3dlc3Qgbm9ybWFsIGRpc3RyaWJ1dGlvbiAoTUxORCkgd2hlcmUgQ1ZtbG5kIFw8IDUuNCBhbmQgdGhlIG1lYW4gb2YgdGhlIGxvd2VyIDIwJSBxdWFudGlsZSAocTAuMikgd2VyZSBDVm1sbmQgXD4gNS40LiBJZiBDVm1sbmQgaXMgbm90IGNhbGN1bGF0ZWQgd2UgaGF2ZSB1c2VkIHEwLjIuDQoNCmBgYHtyfQ0KbGFiY2hhcnRfY2hhYm90X3NtciA8LSBzbG9wZV9kZl9maWx0ZXJfMiAlPiUNCiAgZHBseXI6OmZpbHRlcihwaGFzZSA9PSAic21yIikNCg0KIyBFeHRyYWN0IGRpc3RpbmN0IElEcw0KaWRzIDwtIGxhYmNoYXJ0X2NoYWJvdF9zbXIgJT4lIA0KICBkcGx5cjo6ZGlzdGluY3QoaWQpICU+JSANCiAgZHBseXI6OnB1bGwoKQ0KDQojIEluaXRpYWxpc2UgYW4gZW1wdHkgbGlzdCB0byBzdG9yZSBTTVIgZGF0YQ0Kc21yX2xpc3QgPC0gbGlzdCgpDQoNCiMgUHJvY2VzcyBlYWNoIElEDQpmb3IgKGlkX2kgaW4gaWRzKSB7DQogIHRyeUNhdGNoKHsNCiAgICAjIEZpbHRlciB0aGUgZGF0YSBmb3IgdGhlIGN1cnJlbnQgSUQNCiAgICBkZl9pIDwtIGxhYmNoYXJ0X2NoYWJvdF9zbXIgJT4lIA0KICAgICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogICAgICBkcGx5cjo6bXV0YXRlKGFic19tbzJjb3JyID0gYWJzKG1vMmNvcnIpKQ0KICAgIA0KICAgICMgQ2FsY3VsYXRlIFNNUiByZXN1bHRzDQogICAgY2FsY1NNUl9yZXN1bHRzIDwtIGNhbGNTTVIoZGZfaSRhYnNfbW8yY29ycikNCiAgICBDVm1sbmRfaSA8LSBjYWxjU01SX3Jlc3VsdHMkQ1ZtbG5kDQogICAgcXVhbnRfaSA8LSBjYWxjU01SX3Jlc3VsdHMkcXVhbnQgJT4lIGFzX3RpYmJsZSgpDQogICAgcXVhbnRfMjBwZXJfaSA8LSBxdWFudF9pJHZhbHVlWzNdDQogICAgbWxuZF9pIDwtIGNhbGNTTVJfcmVzdWx0cyRtbG5kDQogICAgc21yX3ZhbHVlIDwtIGlmX2Vsc2UoQ1ZtbG5kX2kgPCA1LjQsIG1sbmRfaSwgcXVhbnRfMjBwZXJfaSkNCiAgICBzbXJfdHlwZSA8LSBpZl9lbHNlKENWbWxuZF9pIDwgNS40LCAibWxuZCIsICJxdWFudF8yMHBlciIpDQogICAgc21yX3ZhbHVlIDwtIGlmX2Vsc2UoaXMubmEoc21yX3ZhbHVlKSwgcXVhbnRfMjBwZXJfaSwgc21yX3ZhbHVlKQ0KICAgIHNtcl90eXBlIDwtIGlmX2Vsc2UoaXMubmEoc21yX3R5cGUpLCAicXVhbnRfMjBwZXIiLCBzbXJfdHlwZSkNCiAgICANCiAgICAjIENyZWF0ZSBhIGRhdGEgZnJhbWUgZm9yIHRoZSBjdXJyZW50IElEDQogICAgc21yX2RmX2kgPC0gdGliYmxlOjp0aWJibGUoDQogICAgICBpZCA9IGlkX2ksDQogICAgICBzbXIgPSBzbXJfdmFsdWUsDQogICAgICBzbXJfZXN0ID0gc21yX3R5cGUNCiAgICApDQogICAgDQogIH0sIGVycm9yID0gZnVuY3Rpb24oZSkgew0KICAgICMgSGFuZGxlIGVycm9ycyBieSBhc3NpZ25pbmcgTkEgdmFsdWVzDQogICAgc21yX2RmX2kgPC0gdGliYmxlOjp0aWJibGUoDQogICAgICBpZCA9IGlkX2ksDQogICAgICBzbXIgPSBOQSwNCiAgICAgIHNtcl9lc3QgPSBOQQ0KICAgICkNCiAgfSkNCiAgDQogICMgQXBwZW5kIHRvIHRoZSBsaXN0DQogIHNtcl9saXN0W1tpZF9pXV0gPC0gc21yX2RmX2kNCn0NCg0KIyBDb21iaW5lIGFsbCBpbmRpdmlkdWFsIFNNUiBkYXRhIGZyYW1lcyBpbnRvIG9uZQ0Kc21yX2RmIDwtIGJpbmRfcm93cyhzbXJfbGlzdCkgJT4lIA0KICBkcGx5cjo6cmVuYW1lKHNtcl9jaGFib3QgPSBzbXIsDQogICAgICAgICAgICAgICAgc21yX2NoYWJvdF9tZXRob2QgPSBzbXJfZXN0KQ0KDQpzbG9wZV9kZl9maWx0ZXJfMyA8LSBzbG9wZV9kZl9maWx0ZXJfMiAlPiUNCiAgZHBseXI6OmxlZnRfam9pbiguLCBzbXJfZGYsIGJ5ID0gImlkIikNCmBgYA0KDQojIyBUcmFuc2Zvcm1pbmcgTU/igoINCg0KSGVyZSB3ZSBhcmUgdHJhbnNmb3JtaW5nIHRoZSBNT+KCgiB1bml0cy4gVGhlIHJlc3VsdGluZyB2YWx1ZXMgYXJlIGFzIGZvbGxvd3M6DQoNCi0gICAqKk1PMioqIGlzIGFic29sdXRlIHZhbHVlIG9mIHRoZSBiYWNrZ3JvdW5kIGFuZCBsZWFrIGNvcnJlY3RlZCBNT+KCgiBzbG9wZSBmcm9tIExhYmNoYXJ0IChtbzJjb3JyKSB0aW1lcyB0aGUgbmV0IHZvbHVtZSBvZiB0aGUgY2hhbWJlciAodm9sdW1lIC0gZmlzaCBtYXNzKSwgw5cgNjAsIMOXIDYwLCB0byBhY2hpZXZlIE1P4oKCIGFzIG1nXi0xXiBP4oKCIGheLTFeDQoNCi0gICAqKk1PMl9nKiogaXMgTU8yIGRpdmlkZWQgYnkgZmlzaCBtYXNzIHRvIGFjaGlldmUgTU/igoIgYXMgbWdeLTFeIE/igoIgZ14tMV4gaF4tMV4gKGkuZS4gbWFzcyBzdGFuZGFyZGlzZWQpDQoNCi0gICAqKlNNUioqIGFic29sdXRlIHZhbHVlIG9mIHRoZSBTTVIgZXN0aW1hdGVzIHVzaW5nIG1ldGhvZHMgZGVzY3JpYmVkIGJ5IENoYWJvdCwgU3RlZmZlbnNlbiBhbmQgRmFycmVsbCAoMjAxNileWzFdXiB0aW1lcyB0aGUgbmV0IHZvbHVtZSBvZiB0aGUgY2hhbWJlciAodm9sdW1lIC0gZmlzaCBtYXNzKSwgw5cgNjAsIMOXIDYwLCB0byBhY2hpZXZlIFNNUiBhcyBtZ14tMV4gT+KCgiBoXi0xXikNCg0KLSAgICoqU01SX2cqKiBpcyBTTVIgZGl2aWRlZCBieSBmaXNoIG1hc3MgdG8gYWNoaWV2ZSBTTVIgYXMgbWdeLTFeIE/igoIgZ14tMV4gaF4tMV4gKGkuZS4gbWFzcyBzdGFuZGFyZGlzZWQpDQoNCi0gICAqKkRPKiogaXMgZGlzc29sdmVkIG94eWdlbiBwZXJjZW50YWdlIGNhbGN1bGF0ZWQgZnJvbSBP4oKCIHZhbHVlcyAobWdeLTFeIExeLTFeKSB1c2luZyB0aGUgcmVjb3JkZWQgdGVtcGVyYXR1cmUsIHNhbGluaXR5LCBhbmQgYSBjb25zdGFudCBhdG1vc3BoZXJpYyBwcmVzc3VyZSAoUGE7IDEwMTMuMjUpDQoNCi0gICAqKm8yX2twYSoqIGlzIHRoZSBP4oKCIGNvbmNlbnRyYXRpb24gaW4ga2lsb3Bhc2NhbCAoa3BhKS4gVGhpcyBpcyB1c2VkIHRvIG1ha2UgYSBjb21wYXJhdGl2ZSBmaWd1cmUgb25seS4NCg0KYGBge3J9DQojIENvbWJpbmUgYmFjayBpbnRvIG9uZSBkYXRhIGZyYW1lDQpzbG9wZV90aWR5IDwtIHNsb3BlX2RmX2ZpbHRlcl8zICU+JSANCiAgICBkcGx5cjo6bXV0YXRlKERPID0gY29udl9vMigNCiAgICAgICAgICAgICAgICAgICBvMiA9IG8yLA0KICAgICAgICAgICAgICAgICAgIGZyb20gPSAibWdfcGVyX2wiLA0KICAgICAgICAgICAgICAgICAgIHRvID0gInBlcmNlbnRfYS5zLiIsDQogICAgICAgICAgICAgICAgICAgdGVtcCA9IHRlbXAsICNDDQogICAgICAgICAgICAgICAgICAgc2FsID0gbWVhc3VyZWRfc2FsaW5pdHksDQogICAgICAgICAgICAgICAgICAgYXRtX3ByZXMgPSAxMDEzLjI1KSwNCiAgICAgICAgICAgICAgICAgIG8yX2twYSA9IGNvbnZfbzIoDQogICAgICAgICAgICAgICAgICAgbzIgPSBvMiwNCiAgICAgICAgICAgICAgICAgICBmcm9tID0gIm1nX3Blcl9sIiwNCiAgICAgICAgICAgICAgICAgICB0byA9ICJrUGEiLA0KICAgICAgICAgICAgICAgICAgIHRlbXAgPSB0ZW1wLCAjQw0KICAgICAgICAgICAgICAgICAgIHNhbCA9IG1lYXN1cmVkX3NhbGluaXR5LA0KICAgICAgICAgICAgICAgICAgIGF0bV9wcmVzID0gMTAxMy4yNSksDQogICAgICAgICAgICAgICAgICBuZXRfdm9sdW1lID0gdm9sdW1lIC0gbWFzcy8xMDAwLA0KICAgICAgICAgICAgICAgICAgTU8yID0gYWJzKG1vMmNvcnIpKm5ldF92b2x1bWUqNjAqNjAsDQogICAgICAgICAgICAgICAgICBNTzJfZyA9IE1PMi9tYXNzLA0KICAgICAgICAgICAgICAgICAgU01SID0gYWJzKHNtcl9jaGFib3QpKm5ldF92b2x1bWUqNjAqNjAsDQogICAgICAgICAgICAgICAgICBTTVJfZyA9IFNNUi9tYXNzDQogICAgICAgICAgICAgICAgICApDQpgYGANCg0KVHJpYWwgbGVuZ3Rocw0KDQpgYGB7cn0NCnNsb3BlX3RpZHkgJT4lIA0KICBkcGx5cjo6ZmlsdGVyKHBoYXNlICE9ICJzbXIiKSAlPiUgDQogIGRwbHlyOjogbXV0YXRlKGRhdGV0aW1lID0gYXMuUE9TSVhjdChwYXN0ZShkYXRlLCB0aW1lX2htcyksIGZvcm1hdCA9ICIlWS0lbS0lZCAlSDolTTolUyIpKSAlPiUNCiAgZHBseXI6Omdyb3VwX2J5KGlkKSAlPiUgDQogIGRwbHlyOjpyZWZyYW1lKA0KICAgIHBoYXNlID0gcGhhc2VbMV0sDQogICAgc3RhcnRfdGltZSA9IG1pbihkYXRldGltZSwgbmEucm0gPSBUUlVFKSwNCiAgICBlbmRfdGltZSA9IG1heChkYXRldGltZSwgbmEucm0gPSBUUlVFKSwNCiAgICB0aW1lX2RpZmYgPSBkaWZmdGltZShlbmRfdGltZSwgc3RhcnRfdGltZSwgdW5pdHMgPSAiaG91cnMiKSAgIyBDaGFuZ2UgdW5pdHMgYXMgbmVlZGVkDQogICkgJT4lIA0KICBkcGx5cjo6Z3JvdXBfYnkocGhhc2UpICU+JSANCiAgZHBseXI6OnJlZnJhbWUoJ01pbmltdW0gZHVyYXRpb24nID0gcm91bmQobWluKHRpbWVfZGlmZiksMiksDQogICAgICAgICAgICAgICAgICdNYXhpbXVtIGR1cmF0aW9uJyA9IHJvdW5kKG1heCh0aW1lX2RpZmYpLDIpLA0KICAgICAgICAgICAgICAgICAnTWVkaWFuIGR1cmF0aW9uJyA9IHJvdW5kKG1lZGlhbih0aW1lX2RpZmYpLDIpKSAlPiUgDQogIGRwbHlyOjptdXRhdGUocGhhc2UgPSBpZl9lbHNlKHBoYXNlID09ICIxMDBjIiwgIkNsb3NlZCBhdCAxMDAlIGFpciBzYXR1cmF0aW9uIiwgIkNsb3NlZCBhdCA3NSUgYW5kIDUwJSBhaXIgc2F0dXJhdGlvbiIpKSAlPiUgDQogIGRwbHlyOjpyZW5hbWUoQXBwcm9hY2ggPSBwaGFzZSkgJT4lIA0KICBndCgpDQogIA0KYGBgDQoNCiMjIFZpc3VhbGlzaW5nIE1PMiBjb3JyZWN0aW9ucyAgDQoNCkxldCdzIGNoZWNrIGhvdyBkYXRhIGNvcnJlY3Rpb25zIGNoYW5nZSB0aGUgYXBwZWFyYW5jZSBvZiBvdXQgZGF0YSANCk1PMg0KDQpMZXQncyBjb21wYXJlIHJhdyBNTzIgY2FsY3VsYXRpb25zIChtbzIpLCBNTzIgY2FsY3VsYXRpb25zIGFmdGVyIGNvcnJlY3RpbmcgYmFja2dyb3VuZCByZXNwaXJhdGlvbiAobW8yX2Jncm91bmQpLCBhbmQgTU8yIGNhbGN1bGF0aW9ucyBhZnRlciBjb3JyZWN0aW5nIGZvciBiYWNrZ3JvdW5kIHJlc3BpcmF0aW9uIGFuZCBveHlnZW4gZGlmZnVzaW9uIGR5bmFtaWNzIChtbzJjb3JyKS4gRmlyc3Qgd2Ugd2lsbCBuZWVkIHRvIG1ha2UgdGhlIG1vMl9iZ3JvdW5kIHZhdWxlIGFzIGl0J3Mgbm90IHByZXNlbnQgaW4gdGhlIGRhdGFmaWxlLCBhbmQgdHJhbnNmb3JtIHRoZSBkYXRhIHRvIGxvbmcgZm9ybWF0ZSwgc28gd2UgY2FuIHBsb3QgaXQgbW9yZSBlYXNseS4NCg0KDQpgYGB7cn0NCnNsb3BlX2NvcnJfY29tcCA8LSBzbG9wZV90aWR5ICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KGlkKSAlPiUgDQogIGRwbHlyOjptdXRhdGUoDQogICAgTU8yX3JhdyA9IGFicyhtbzIpICogbmV0X3ZvbHVtZSAqIDYwICogNjAsDQogICAgTU8yX2Jncm91bmRfY29yciA9IGFicyhtbzIgLSBiZ3JvdW5kKSAqIG5ldF92b2x1bWUgKiA2MCAqIDYwLA0KICAgIE1PMl9jb3JyID0gYWJzKG1vMmNvcnIpICogbmV0X3ZvbHVtZSAqIDYwICogNjANCiAgKSAlPiUgDQogIGRwbHlyOjpzZWxlY3QoaWQsIG9yZGVyLCBETywgTU8yX3JhdywgTU8yX2Jncm91bmRfY29yciwgTU8yX2NvcnIpICU+JSANCiAgdGlkeXI6OnBpdm90X2xvbmdlcigNCiAgICBjb2xzID0gYyhNTzJfcmF3LCBNTzJfYmdyb3VuZF9jb3JyLCBNTzJfY29yciksIA0KICAgIG5hbWVzX3RvID0gIk1PMl90eXBlIg0KICApICU+JQ0KICBkcGx5cjo6bXV0YXRlKA0KICAgIE1PMl90eXBlID0gZm9yY2F0czo6ZmN0X3JlbGV2ZWwoTU8yX3R5cGUsICJNTzJfcmF3IiwgIk1PMl9iZ3JvdW5kX2NvcnIiLCAiTU8yX2NvcnIiKQ0KICApICU+JQ0KICBkcGx5cjo6dW5ncm91cCgpDQpgYGANCg0KIyMjIEZpZ3VyZSBTMQ0KDQpOb3cgbGV0J3MgcGxvdCB0aGVtIGluIHRoZSBzYW1lIGdyYXBoIGZvciBlYWNoIGZpc2g6IA0KPHNwYW4gc3R5bGU9ImNvbG9yOiNmNjkyQjQiPnJhdyBNT+KCgiBjYWxjdWxhdGlvbnM8L3NwYW4+IGFyZSBzaG93biBpbiBwaW5rLCANCjxzcGFuIHN0eWxlPSJjb2xvcjojNkU3ODg5Ij5NT+KCgiBjYWxjdWxhdGlvbnMgYWZ0ZXIgY29ycmVjdGluZyBmb3IgYmFja2dyb3VuZCByZXNwaXJhdGlvbjwvc3Bhbj4gYXJlIHNob3duIGluIGdyZXksIGFuZCANCjxzcGFuIHN0eWxlPSJjb2xvcjojNTNhZjhiIj5NT+KCgiBjYWxjdWxhdGlvbnMgYWZ0ZXIgY29ycmVjdGluZyBmb3IgYmFja2dyb3VuZCByZXNwaXJhdGlvbiBhbmQgb3h5Z2VuIGRpZmZ1c2lvbiBkeW5hbWljczwvc3Bhbj4gYXJlIHNob3duIGluIGdyZWVuLg0KDQoNCmBgYHtyLCBmaWcuaGVpZ2h0ID0gOCwgZmlnLndpZHRoPSAxMH0NCiMgRGVmaW5lIHlvdXIgY3VzdG9tIGNvbG91ciBzY2hlbWUNCnBsb3RfY29sb3VycyA8LSBjKCIjZjY5MkI0IiwgIiM2RTc4ODkiLCAiIzUzYWY4YiIpDQoNCiMgQ29sbGVjdCB1bmlxdWUgZmlzaCBJRHMNCmZpc2hfaWRzIDwtIHNsb3BlX2NvcnJfY29tcCAlPiUgDQogIGRwbHlyOjpkaXN0aW5jdChpZCkgJT4lIA0KICBkcGx5cjo6cHVsbChpZCkNCg0KIyBDcmVhdGUgYSBsaXN0IHRvIHN0b3JlIHBsb3RzDQpwbG90X2xpc3QgPC0gbGlzdCgpDQoNCiMgR2VuZXJhdGUgcGxvdHMgYW5kIGFkZCB0aGVtIHRvIHRoZSBsaXN0DQpmb3IgKGlkX2kgaW4gZmlzaF9pZHMpIHsNCiAgcGxvdF9pIDwtIHNsb3BlX2NvcnJfY29tcCAlPiUgDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogICAgZ2dwbG90KGFlcyh4ID0gRE8sIHkgPSB2YWx1ZSwgY29sb3VyID0gTU8yX3R5cGUpKSArDQogICAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSkgKw0KICAgIHRoZW1lX2NsZWFuKCkgKw0KICAgIGxhYnMoDQogICAgICBzdWJ0aXRsZSA9IGlkX2ksDQogICAgICB4ID0gIkRpc3NvbHZlZCBveHlnZW4gcGVyY2VudGFnZSAoRE8pIiwNCiAgICAgIHkgPSAiTU8yIChPMiBtZy9nL2gpIg0KICAgICkgKw0KICAgIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gcGxvdF9jb2xvdXJzKSArDQogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KICANCiAgcGxvdF9saXN0W1tpZF9pXV0gPC0gcGxvdF9pDQp9DQoNCiMgQ29tYmluZSBwbG90cyBpbiBwYWdlcyBvZiA5ICgzIGNvbHVtbnMgeCAzIHJvd3MpDQpwbG90c19wZXJfcGFnZSA8LSA5DQpuX3BhZ2VzIDwtIGNlaWxpbmcobGVuZ3RoKHBsb3RfbGlzdCkgLyBwbG90c19wZXJfcGFnZSkNCg0KIyBEaXNwbGF5IGVhY2ggcGFnZQ0KZm9yIChpIGluIHNlcV9sZW4obl9wYWdlcykpIHsNCiAgc3RhcnQgPC0gKGkgLSAxKSAqIHBsb3RzX3Blcl9wYWdlICsgMQ0KICBlbmQgPC0gbWluKGkgKiBwbG90c19wZXJfcGFnZSwgbGVuZ3RoKHBsb3RfbGlzdCkpDQogIHBhZ2VfcGxvdHMgPC0gcGF0Y2h3b3JrOjp3cmFwX3Bsb3RzKHBsb3RfbGlzdFtzdGFydDplbmRdLCBuY29sID0gMykNCiAgcHJpbnQocGFnZV9wbG90cykNCn0NCmBgYA0KDQoNCioqRmlndXJlIFMxKio6IEluZGl2aWR1YWwgZmlzaC1sZXZlbCBwbG90cyBzaG93aW5nIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBkaXNzb2x2ZWQgb3h5Z2VuIChETykgcGVyY2VudGFnZSBhbmQgbWV0YWJvbGljIG94eWdlbiBjb25zdW1wdGlvbiByYXRlIChNT+KCgiwgaW4gbWcgT+KCgi9nL2gpIGZvciBlYWNoIDIwLW1pbiBpbnRlcnZhbC4gRWFjaCBwYW5lbCBkaXNwbGF5cyBkYXRhIGZvciBhIHNpbmdsZSBmaXNoIChmaXNoIElEIGluIHRoZSB0b3AgbGVmdCBvZiB0aGUgcGxvdCkuIFBvaW50cyBhcmUgY29sb3VyLWNvZGVkIGJ5IHRoZSB0eXBlIG9mIE1P4oKCIGNhbGN1bGF0aW9uOg0KPHNwYW4gY2xhc3M9InBpbmsiPnJhdyBNT+KCgjwvc3Bhbj4gKHBpbmssICNmNjkyQjQpLA0KPHNwYW4gY2xhc3M9ImdyZXkiPmJhY2tncm91bmQtY29ycmVjdGVkIE1P4oKCPC9zcGFuPiAoZ3JleSwgIzZFNzg4OSksIGFuZA0KPHNwYW4gY2xhc3M9ImdyZWVuIj5mdWxseSBjb3JyZWN0ZWQgTU/igoIgKGFjY291bnRpbmcgZm9yIGJhY2tncm91bmQgcmVzcGlyYXRpb24gYW5kIG94eWdlbiBkaWZmdXNpb24gZHluYW1pY3MpPC9zcGFuPiAoZ3JlZW4sICM1M2FmOGIpLg0KRWFjaCBwb2ludCByZXByZXNlbnRzIGEgbWVhc3VyZW1lbnQgYXQgYSBzcGVjaWZpYyBETyBsZXZlbCwgYW5kIHRoZSBzbGlnaHQgdHJhbnNwYXJlbmN5IChhbHBoYSA9IDAuNSkgaGlnaGxpZ2h0cyBvdmVybGFwcGluZyBvYnNlcnZhdGlvbnMuDQoNCjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT4NCg0KIyDwn5OKIEV4cGxvcmF0b3J5IERhdGEgQW5hbHlzaXMgKEVEQSkNCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQojIyBP4oKCIHZzIE1P4oKCDQoNCiMjIyBGaWd1cmUgUzINCg0KVGhpcyBpbnRlcmFjdGl2ZSB3YXMgdXNlZCB0byBpZGVudGlmeSBhbnkgb3V0bGllcnMsIG9yIHBvdGVudGlhbCBlcnJvcnMuIFRoaXMgaGFzIG5vdCBiZWVuIGdlbmVyYXRlZCBpbiB0aGUgUERGIGBTdXBwbGVtZW50YXJ5IGZpbGUgMWAsIGFzIGl0IGlzIG5vdCBjb21wYXRpYmxlLiANCg0KYGBge3J9DQpsbV9saW5lcyA8LSBzbG9wZV90aWR5ICU+JQ0KICBncm91cF9ieShpZCkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBET19zZXEgPSBsaXN0KHNlcShtaW4oRE8pLCBtYXgoRE8pLCBsZW5ndGgub3V0ID0gMTAwKSksICAjIEdlbmVyYXRlIGEgc2VxdWVuY2Ugb2YgRE8gdmFsdWVzDQogICAgTU8yX3ByZWQgPSBsaXN0KHByZWRpY3QobG0oTU8yX2cgfiBETywgZGF0YSA9IGN1cl9kYXRhKCkpLCBuZXdkYXRhID0gZGF0YS5mcmFtZShETyA9IHNlcShtaW4oRE8pLCBtYXgoRE8pLCBsZW5ndGgub3V0ID0gMTAwKSkpKQ0KICApICU+JQ0KICB1bm5lc3QoYyhET19zZXEsIE1PMl9wcmVkKSkgICMgRXhwYW5kIGxpc3RzIGludG8gcm93cw0KDQojIENyZWF0ZSBzY2F0dGVyIHBsb3Qgd2l0aCBtYXJrZXJzIGZvciBlYWNoIGZpc2gNCnAgPC0gcGxvdF9seSgNCiAgZGF0YSA9IHNsb3BlX3RpZHksDQogIHggPSB+RE8sDQogIHkgPSB+TU8yX2csDQogIHR5cGUgPSAic2NhdHRlciIsDQogIG1vZGUgPSAibWFya2VycyIsDQogIGNvbG9yID0gfmlkLCAgIyBDb2xvdXIgcG9pbnRzIGJ5IGZpc2ggSUQNCiAgbWFya2VyID0gbGlzdChvcGFjaXR5ID0gMC42KSwNCiAgbmFtZSA9IH5pZA0KKQ0KDQojIEFkZCByZWdyZXNzaW9uIGxpbmVzIGZvciBlYWNoIGZpc2gNCnAgPC0gcCAlPiUNCiAgYWRkX3RyYWNlKA0KICAgIGRhdGEgPSBsbV9saW5lcywNCiAgICB4ID0gfkRPX3NlcSwNCiAgICB5ID0gfk1PMl9wcmVkLA0KICAgIHR5cGUgPSAic2NhdHRlciIsDQogICAgbW9kZSA9ICJsaW5lcyIsDQogICAgY29sb3IgPSB+aWQsICAjIEVuc3VyZSBlYWNoIGxpbmUgbWF0Y2hlcyBpdHMgY29ycmVzcG9uZGluZyBmaXNoDQogICAgbGluZSA9IGxpc3Qod2lkdGggPSAxLCBkYXNoID0gInNvbGlkIiksDQogICAgc2hvd2xlZ2VuZCA9IEZBTFNFICAjIEF2b2lkIGNsdXR0ZXJpbmcgdGhlIGxlZ2VuZA0KICApDQoNCiMgRmluYWwgbGF5b3V0DQpwIDwtIHAgJT4lDQogIGxheW91dCgNCiAgICB0aXRsZSA9ICJNTzxzdWI+Mjwvc3ViPiB2cyBEaXNzb2x2ZWQgT3h5Z2VuIHdpdGggaW5kaXZpZHVhbCBsaW5lYXIgcmVncmVzc2lvbnMiLA0KICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICJEaXNzb2x2ZWQgT3h5Z2VuICglKSIpLA0KICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJNTzxzdWI+Mjwvc3ViPiAobWc8c3VwPi0xPC9zdXA+IE88c3ViPjI8L3N1Yj4gZzxzdXA+LTE8L3N1cD4gaDxzdXA+LTE8L3N1cD4pIiksDQogICAgc2hvd2xlZ2VuZCA9IEZBTFNFDQogICkNCg0KIyBEaXNwbGF5IHBsb3QNCnANCmBgYA0KDQoqKipGaWd1cmUgUzI6KioqIGludGVyYWN0aXZlIHBsb3Qgb2YgbWV0YWJvbGljIHJhdGUgbWVhc3VyZW1lbnRzIChNT+KCgjsgbWcgT+KCgiBnXi0xXmheLTFeKSBieSBkaXNzb2x2ZWQgb3h5Z2VuIHBlcmNlbnRhZ2UgKERPKSBmb3IgYWxsIGZpc2gsIGluY2x1ZGluZyBhbGwgZXN0aW1hdGVzIGR1cmluZyB0aGUgU01SIHBoYXNlIChpLmUuIGludGVybWl0dGVudCBwaGFzZSkuIEluZGl2aWR1YWwgbGluZWFyIHJlZ3Jlc3Npb24gd2VyZSBmaXR0ZWQgZm9yIHZpc3VhbCByZWZlcmVuY2UsIGFuZCBkbyBub3QgcmVwcmVzZW50IHRoZSBiZXN0IGZpdHRpbmcgcmVncmVzc2lvbi4NCg0KIyMjIEZpZ3VyZSBTMw0KDQpMb29raW5nIGF0IHRoZSBkaWZmZXJlbmNlIHJlc3BvbnNlcyBpbiB0aGUgdHdvIHNhbGluaXR5IGdyb3Vwcy4NCg0KYGBge3J9DQpzYWxpbml0eV9zdW1tYXJ5IDwtIHNsb3BlX3RpZHkgJT4lIA0KICBkcGx5cjo6Z3JvdXBfYnkoc2FsaW5pdHlfZ3JvdXApICU+JSANCiAgZHBseXI6OnJlZnJhbWUobiA9IGxlbmd0aCh1bmlxdWUoaWQpKSkNCg0Kc2xvcGVfdGlkeSAlPiUgDQogIGdncGxvdChhZXMoeSA9IE1PMl9nLCB4ID0gRE8sIGNvbG91ciA9IGlkKSkgKyANCiAgZ2VvbV9wb2ludChzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGlkKSwgbWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSwgY29sb3VyID0gc2NhbGVzOjphbHBoYSgiYmxhY2siLCAwLjUpKSArICMgVHJhbnNwYXJlbnQgYmxhY2sgbGluZXMNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBUUlVFLCBjb2xvdXIgPSAicmVkIikgKyAjIE92ZXJhbGwgc21vb3RoIGxpbmUNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImdhbSIsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIpLCBzZSA9IFRSVUUsIGNvbG91ciA9ICJyZWQiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHRoZW1lX2NsZWFuKCkgKw0KICBmYWNldF93cmFwKH5zYWxpbml0eV9ncm91cCkgKw0KICBsYWJzKA0KICAgIHN1YnRpdGxlID0gIm1vMiB2cyBvMiBieSBzYWxpbml0eSB0cmVhdG1lbnQiLA0KICAgIHggPSAiRGlzc29sdmVkIG94eWdlbiBwZXJjZW50YWdlIChETykiLA0KICAgIHkgPSAiTU8yIChPMiBtZy9nL2gpIg0KICApICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBzYWxpbml0eV9zdW1tYXJ5LA0KICAgICAgICAgICAgYWVzKHggPSAtSW5mLCB5ID0gSW5mLCBsYWJlbCA9IHBhc3RlMCgiaXRhbGljKG4pID09ICIsIG4pKSwNCiAgICAgICAgICAgIGhqdXN0ID0gLTAuMSwgdmp1c3QgPSAxLjIsIGluaGVyaXQuYWVzID0gRkFMU0UsIHBhcnNlID0gVFJVRSkNCmBgYA0KDQoqKipGaWd1cmUgUzM6KioqIE1ldGFib2xpYyByYXRlIG1lYXN1cmVtZW50cyAoTU/igoI7IG1nIE/igoIgZ14tMV5oXi0xXikgYnkgZGlzc29sdmVkIG94eWdlbiBwZXJjZW50YWdlIChETykgZm9yIGZpc2ggZnJvbSB0aGUgdHdvIHNhbGluaXR5IHRyZWF0bWVudHMsIGluY2x1ZGluZyBhbGwgZXN0aW1hdGVzIGR1cmluZyB0aGUgU01SIHBoYXNlIChpLmUuIGludGVybWl0dGVudCBwaGFzZSkuIEluZGl2aWR1YWwgbGluZWFyIHJlZ3Jlc3Npb24gd2VyZSBmaXR0ZWQgZm9yIHZpc3VhbCByZWZlcmVuY2UsIGFuZCBkbyBub3QgcmVwcmVzZW50IHRoZSBiZXN0IGZpdHRpbmcgcmVncmVzc2lvbi4gVGhlIHNvbGlkIHJlZCBhbmQgZGFzaGVkIHJlZCBsaW5lIHJlcHJlc2VudHMgdGhlIGdsb2JhbCB0cmVuZCBpbiBlYWNoIG9mIHRoZSB0cmVhdG1lbnRzLCBib3RoIGEgbGluZWFyIChzb2xpZCByZWQpIGFuZCBub24tbGluZWFyIChkYXNoZWQgcmVkOyBHZW5lcmFsaXplZCBBZGRpdGl2ZSBNb2RlbCBmaXR0ZWQgd2l0aCBgZ2VvbV9zbW9vdGhgKS4NCg0KIyMjIEZpZ3VyZSBTNA0KDQpBIHBsb3QgdG8gbG9vayBhdCB0aGUgZGlmZmVyZW50IGNoYW1iZXIgdHlwZXMNCg0KYGBge3J9DQpjaGFtYmVyX3N1bW1hcnkgPC0gc2xvcGVfdGlkeSAlPiUgDQogIGRwbHlyOjpncm91cF9ieShjaGFtYmVyX3R5cGUpICU+JSANCiAgZHBseXI6OnJlZnJhbWUobiA9IGxlbmd0aCh1bmlxdWUoaWQpKSkNCg0Kc2xvcGVfdGlkeSAlPiUgDQogIGdncGxvdChhZXMoeSA9IE1PMl9nLCB4ID0gRE8sIGNvbG91ciA9IGlkKSkgKyANCiAgZ2VvbV9wb2ludChzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGlkKSwgbWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSwgY29sb3VyID0gc2NhbGVzOjphbHBoYSgiYmxhY2siLCAwLjUpKSArICMgVHJhbnNwYXJlbnQgYmxhY2sgbGluZXMNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBUUlVFLCBjb2xvdXIgPSAicmVkIikgKyAjIE92ZXJhbGwgc21vb3RoIGxpbmUNCiAgZ2VvbV9zbW9vdGgoc2UgPSBUUlVFLCBjb2xvdXIgPSAicmVkIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB0aGVtZV9jbGVhbigpICsNCiAgZmFjZXRfd3JhcCh+Y2hhbWJlcl90eXBlLCBzY2FsZSA9ICJmcmVlIikgKw0KICBsYWJzKA0KICAgIHN1YnRpdGxlID0gIm1vMiB2cyBvMiBieSBjaGFtYmVyIHR5cGUiLA0KICAgIHggPSAiRGlzc29sdmVkIG94eWdlbiBwZXJjZW50YWdlIChETykiLA0KICAgIHkgPSAiTU8yIChtZyBPMiBnL2gpIg0KICApICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBjaGFtYmVyX3N1bW1hcnksDQogICAgICAgICAgICBhZXMoeCA9IC1JbmYsIHkgPSBJbmYsIGxhYmVsID0gcGFzdGUwKCJpdGFsaWMobikgPT0gIiwgbikpLA0KICAgICAgICAgICAgaGp1c3QgPSAtMC4xLCB2anVzdCA9IDEuMiwgaW5oZXJpdC5hZXMgPSBGQUxTRSwgcGFyc2UgPSBUUlVFKQ0KYGBgDQoNCioqKkZpZ3VyZSBTNDoqKiogTWV0YWJvbGljIHJhdGUgbWVhc3VyZW1lbnRzIChNT+KCgjsgbWcgT+KCgiBnXi0xXmheLTFeKSBieSBkaXNzb2x2ZWQgb3h5Z2VuIHBlcmNlbnRhZ2UgKERPKSBmb3IgZmlzaCB0ZXN0ZWQgaW4gdGhlIDQgZGlmZmVyZW50IGNoYW1iZXIgdHlwZXMsIGluY2x1ZGluZyBhbGwgZXN0aW1hdGVzIGR1cmluZyB0aGUgU01SIHBoYXNlIChpLmUuIGludGVybWl0dGVudCBwaGFzZSkuIEluZGl2aWR1YWwgbGluZWFyIHJlZ3Jlc3Npb24gd2VyZSBmaXR0ZWQgZm9yIHZpc3VhbCByZWZlcmVuY2UsIGFuZCBkbyBub3QgcmVwcmVzZW50IHRoZSBiZXN0IGZpdHRpbmcgcmVncmVzc2lvbi4gVGhlIHNvbGlkIHJlZCBhbmQgZGFzaGVkIHJlZCBsaW5lIHJlcHJlc2VudHMgdGhlIGdsb2JhbCB0cmVuZCBpbiBlYWNoIG9mIHRoZSB0cmVhdG1lbnRzLCBib3RoIGEgbGluZWFyIChzb2xpZCByZWQpIGFuZCBub24tbGluZWFyIChkYXNoZWQgcmVkOyBHZW5lcmFsaXplZCBBZGRpdGl2ZSBNb2RlbCBmaXR0ZWQgd2l0aCBgZ2VvbV9zbW9vdGhgKS4NCg0KDQojIyBSb3V0aW5lIE1P4oKCDQoNCk1ha2luZyBhbiBTTVIgcGhhc2Ugb25seSBkYXRhIGZyYW1lDQoNCmBgYHtyfQ0Kc2xvcGVfdGlkeV9zbXIgPC0gc2xvcGVfdGlkeSAlPiUgDQogIGRwbHlyOjpmaWx0ZXIocGhhc2UgPT0gInNtciIpDQpgYGANCg0KDQpSb3V0aW5lIE1PPHN1Yj4yPC9zdWI+IGJ5IHNhbGluaXR5LiBQbG90IG9mIGFsbCBNTzxzdWI+Mjwvc3ViPiBtZWFzdXJlcyBkdXJpbmcgU01SIHBoYXNlIGJ5IHNhbGluaXR5IHRyZWF0bWVudC4gVGhlIHNtYWxsIHBvaW50cyBhcmUgdGhlIHJhdyBvYnNlcnZlZCB2YWx1ZXMsIHRoZSBzaGFkZWQgYXJlYSBiZWhpbmQgdGhlIHBvaW50cyBpcyB0aGUgYSBrZXJuZWwgZGVuc2l0eSBvZiB0aGUgb2JzZXJ2ZWQgZGF0YSwgdGhlIGJveCBwbG90IHNob3dzIHRoZSBtZWRpYW4gYW5kIGludGVycXVhcnRpbGUgcmFuZ2UgKElRUiksIGFuZCB0aGUgbGFyZ2UgcG9pbnQgc2hvd3MgdGhlIG1lYW4uDQoNCmBgYHtyfQ0KbWVhbl9tbzJfc2FsaW5pdHkgPC0gc2xvcGVfdGlkeV9zbXIgJT4lIA0KICBkcGx5cjo6Z3JvdXBfYnkoc2FsaW5pdHlfZ3JvdXApICU+JSANCiAgZHBseXI6OnJlZnJhbWUobWVhbl9tbzIgPSBtZWFuKE1PMiwgbmEucm0gPSBUUlVFKSkNCg0KZmlnX2kgPC0gZ2dwbG90KCkgKw0KICAgIGdlb21fdmlvbGluKGRhdGEgPSBzbG9wZV90aWR5X3NtciwgYWVzKHggPSBzYWxpbml0eV9ncm91cCwgeSA9IE1PMiwgZmlsbCA9IHNhbGluaXR5X2dyb3VwKSwgY29sb3IgPSBOQSwgYWxwaGEgPSAwLjMpICsNCiAgZ2VvbV9qaXR0ZXIoZGF0YSA9IHNsb3BlX3RpZHlfc21yLCBhZXMoeCA9IHNhbGluaXR5X2dyb3VwLCB5ID0gTU8yLCBmaWxsID0gc2FsaW5pdHlfZ3JvdXApLA0KICAgICAgICAgICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBzaXplID0gMiwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuMikgKw0KICBnZW9tX2JveHBsb3QoZGF0YSA9IHNsb3BlX3RpZHlfc21yLCBhZXMoeCA9IHNhbGluaXR5X2dyb3VwLCB5ID0gTU8yLCBmaWxsID0gc2FsaW5pdHlfZ3JvdXApLA0KICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDEsIGFscGhhID0gMC41LCBvdXRsaWVyLnNoYXBlID0gTkEsIHdpZHRoID0gMC4zKSArDQogIGdlb21fcG9pbnQoZGF0YSA9IG1lYW5fbW8yX3NhbGluaXR5LCANCiAgICAgICAgICAgICAgICBhZXMoeCA9IHNhbGluaXR5X2dyb3VwLCB5ID0gbWVhbl9tbzIsIGZpbGwgPSBzYWxpbml0eV9ncm91cCksIA0KICAgICAgICAgICAgICAgIHNpemUgPSAzLCBhbHBoYSA9IDAuOCwgY29sb3VyID0gImJsYWNrIiwgc3Ryb2tlID0gMikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjNEI1MzIwIiwgIiMwMDAwODAiKSkgKyAgIyBDdXN0b20gZmlsbCBjb2xvdXJzDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiIzRCNTMyMCIsICIjMDAwMDgwIikpICsNCiAgdGhlbWVfY2xlYW4oKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICBsYWJzKA0KICAgIHN1YnRpdGxlID0gIiIsDQogICAgeCA9ICJTYWxpbml0eSBncm91cCAocHB0KSIsDQogICAgeSA9ICJSb3V0aW5lIE1PMiAobWcgTzIgZy9oKSINCiAgKQ0KDQpmaWdfaQ0KYGBgDQoNCg0KIyMgU01SDQoNCkhlcmUncyB0aGUgc2FtZSBwbG90IGJ1dCBmb3Igb25seSB0aGUgU01SLCBhcyBlc3RpbWF0ZWQgd2l0aCBjYWxjU01SIGZ1bmN0aW9uIGJ5IENoYWJvdCwgU3RlZmZlbnNlbiBhbmQgRmFycmVsbCAoMjAxNileWzFdXi4gU3BlY2lmaWNhbGx5LCB3ZSB1c2UgbWVhbiBvZiB0aGUgbG93ZXN0IG5vcm1hbCBkaXN0cmlidXRpb24gKE1MTkQpIHdoZXJlIENWbWxuZCBcPCA1LjQgYW5kIHRoZSBtZWFuIG9mIHRoZSBsb3dlciAyMCUgcXVhbnRpbGUgKHEwLjIpIHdlcmUgQ1ZtbG5kIFw+IDUuNC4gSWYgQ1ZtbG5kIGlzIG5vdCBjYWxjdWxhdGVkIHdlIGhhdmUgdXNlZCBxMC4yLg0KDQpgYGB7cn0NCnNtcl9vbmx5IDwtIHNsb3BlX3RpZHlfc21yICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KGlkKSAlPiUgDQogIGRwbHlyOjpzbGljZSgxKQ0KDQptZWFuX3Ntcl9zYWxpbml0eSA8LSBzbXJfb25seSAlPiUgDQogIGRwbHlyOjpncm91cF9ieShzYWxpbml0eV9ncm91cCkgJT4lIA0KICBkcGx5cjo6cmVmcmFtZShtZWFuX3NtciA9IG1lYW4oU01SLCBuYS5ybSA9IFRSVUUpKQ0KDQpmaWdfaSA8LSBnZ3Bsb3QoKSArDQogICAgZ2VvbV92aW9saW4oZGF0YSA9IHNtcl9vbmx5LCBhZXMoeCA9IHNhbGluaXR5X2dyb3VwLCB5ID0gU01SLCBmaWxsID0gc2FsaW5pdHlfZ3JvdXApLCBjb2xvciA9IE5BLCBhbHBoYSA9IDAuMykgKw0KICBnZW9tX2ppdHRlcihkYXRhID0gc21yX29ubHksIGFlcyh4ID0gc2FsaW5pdHlfZ3JvdXAsIHkgPSBTTVIsIGZpbGwgPSBzYWxpbml0eV9ncm91cCksDQogICAgICAgICAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHNpemUgPSAyLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC4yKSArDQogIGdlb21fYm94cGxvdChkYXRhID0gc21yX29ubHksIGFlcyh4ID0gc2FsaW5pdHlfZ3JvdXAsIHkgPSBTTVIsIGZpbGwgPSBzYWxpbml0eV9ncm91cCksDQogICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gMSwgYWxwaGEgPSAwLjUsIG91dGxpZXIuc2hhcGUgPSBOQSwgd2lkdGggPSAwLjMpICsNCiAgZ2VvbV9wb2ludChkYXRhID0gbWVhbl9zbXJfc2FsaW5pdHksIA0KICAgICAgICAgICAgICAgIGFlcyh4ID0gc2FsaW5pdHlfZ3JvdXAsIHkgPSBtZWFuX3NtciwgZmlsbCA9IHNhbGluaXR5X2dyb3VwKSwgDQogICAgICAgICAgICAgICAgc2l6ZSA9IDMsIGFscGhhID0gMC44LCBjb2xvdXIgPSAiYmxhY2siLCBzdHJva2UgPSAyKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM0QjUzMjAiLCAiIzAwMDA4MCIpKSArICAjIEN1c3RvbSBmaWxsIGNvbG91cnMNCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCIjNEI1MzIwIiwgIiMwMDAwODAiKSkgKw0KICB0aGVtZV9jbGVhbigpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogIGxhYnMoDQogICAgc3VidGl0bGUgPSAiIiwNCiAgICB4ID0gIlNhbGluaXR5IGdyb3VwIChwcHQpIiwNCiAgICB5ID0gIk1PMiAobWcgTzIgZy9oKSINCiAgKQ0KDQpmaWdfaQ0KYGBgDQoNCiMjIEluZGl2aWR1YWwgT+KCgiwgTU/igoIsIGFuZCBTTVINCg0KSGVyZSB3ZSB3aWxsIHBsb3QgdGhlIGluZGl2aWR1YWwgcmVsYXRpb25zaGlwIGJldHdlZW4gT+KCgiwgTU/igoIsIGFuZCBTTVIgZm9yIGFsbCBmaXNoDQoNCkNyZWF0ZSBvdXRwdXQgZGlyZWN0b3J5IGlmIG5lZWRlZA0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCiMgQ3JlYXRlIG91dHB1dCBkaXJlY3RvcnkgaWYgbmVlZGVkDQpvdXRwdXRfZmlnX3Nsb3Blc193ZCA8LSBmaWxlLnBhdGgob3V0cHV0X2ZpZ193ZCwgInNsb3BlcyIpDQppZiAoIWRpci5leGlzdHMob3V0cHV0X2ZpZ19zbG9wZXNfd2QpKSB7DQogIGRpci5jcmVhdGUob3V0cHV0X2ZpZ19zbG9wZXNfd2QpDQp9DQpgYGANCg0KTG9vcCB0aHJvdWdoIGVhY2ggZmlzaCBJRCB0byBjcmVhdGUgYSBwbG90LCBzYXZlIHRoZXNlIHRvIGEgc2luZ2xlIFBERiBmaWxlLCB0aGlzIGlzIGNhbGxlZCBgY29tYmluZWRfc2xvcGVzLnBkZmAuIEl0IGNhbiBiZSBmb3VuZCBpbiB0aGlzIHBhdGggYG91dHB1dC1maWcvc2xvcGVzL2NvbWJpbmVkX3Nsb3Blcy5wZGZgIA0KVGhlc2UgcGxvdHMgc2hvdyBNZXRhYm9saWMgcmF0ZSBtZWFzdXJlbWVudHMgKE1P4oKCOyBtZyBP4oKCIGdeLTFeaF4tMV4gYnkgTzxzdWI+Mjwvc3ViPikgYXQgZWFjaCBvZiB0aGUgZm91ciBleHBlcmltZW50YWwgcGhhc2UgKHRoZSBvdmVyIG5pZ2h0IFNNUiBpbnRlcm1pdHRlbnQtZmxvdyByZXNwaXJvbWV0cnkgcGhhc2UsIGNsb3NlZCBwaGFzZXMgYXQgNTAlLCA3NSUgb3IgMTAwJSBPPHN1Yj4yPC9zdWI+KS4gVGhlIGVzdGltYXRlZCBTTVIgdmFsdWUgaXMgcmVwcmVzZW50ZWQgYXMgYSBkYXNoZWQgcmVkIGxpbmUuDQoNCmBgYHtyLCBmaWcuaGVpZ2h0ID0gMywgZmlnLndpZHRoPSA0fQ0KIyBEZWZpbmUgY29uc2lzdGVudCBjb2xvcnMgZm9yIGFsbCBwaGFzZXMNCnBoYXNlX2NvbG9ycyA8LSBjKA0KICAiNTBjIiAgPSAiI2U1NmI2ZiIsDQogICI3NWMiICA9ICIjYjU2NTc2IiwNCiAgIjEwMGMiID0gIiM2ZDU5N2EiLA0KICAic21yIiAgPSAiIzM1NTA3MCINCikNCg0KaWRzIDwtIHNsb3BlX3RpZHkgJT4lDQogIGRwbHlyOjpkaXN0aW5jdChpZCkgJT4lDQogIHB1bGwoaWQpICU+JQ0KICBhcy5saXN0KCkNCg0KTU8yX3Bsb3RfbGlzdCA8LSBsaXN0KCkNCg0KIyAxKSBPcGVuIHRoZSBQREYgZGV2aWNlIG9uY2UNCnBkZigNCiAgZmlsZSAgID0gZmlsZS5wYXRoKG91dHB1dF9maWdfc2xvcGVzX3dkLCAiY29tYmluZWRfc2xvcGVzLnBkZiIpLA0KICB3aWR0aCAgPSA4LA0KICBoZWlnaHQgPSA2DQopDQoNCiMgMikgTG9vcCBvdmVyIElEcyBhbmQgY3JlYXRlIGVhY2ggcGxvdA0KZm9yIChpZF9pIGluIGlkcykgew0KDQogIHNtciA8LSBzbG9wZV90aWR5ICU+JQ0KICAgIGRwbHlyOjpmaWx0ZXIoaWQgPT0gaWRfaSkgJT4lDQogICAgZHBseXI6OnNsaWNlKDEpICU+JQ0KICAgIGRwbHlyOjpwdWxsKFNNUikNCg0KICBwbG90IDwtIHNsb3BlX3RpZHkgJT4lDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUNCiAgICBnZ3Bsb3QoYWVzKHggPSBvMiwgeSA9IE1PMikpICsNCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBzbXIsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gImRhcmtyZWQiKSArDQogICAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gcGhhc2UpKSArDQogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHBoYXNlX2NvbG9ycywgZHJvcCA9IEZBTFNFKSArICAjIEVuc3VyZXMgY29uc2lzdGVudCBjb2xvdXJzDQogICAgdGhlbWVfY2xlYW4oKSArDQogICAgbGFicygNCiAgICAgIHN1YnRpdGxlID0gcGFzdGUwKGlkX2ksICIgc2xvcGVzIiksDQogICAgICB4ID0gIk1lYW4gbzIgKG1nX3Blcl9sKSIsDQogICAgICB5ID0gImFicyhtbzIpIChtZ19wZXJfbCkiDQogICAgKQ0KDQogICMgSW5zdGVhZCBvZiBzYXZpbmcgZWFjaCBwbG90IHNlcGFyYXRlbHksIGp1c3QgcHJpbnQgaXQNCiAgcHJpbnQocGxvdCkNCg0KICBNTzJfcGxvdF9saXN0W1tpZF9pXV0gPC0gcGxvdA0KfQ0KDQojIDMpIENsb3NlIHRoZSBQREYgZGV2aWNlICphZnRlciogdGhlIGxvb3ANCmRldi5vZmYoKQ0KYGBgDQoNCjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT4NCg0KIyDwn6euIEFuYWx5c2lzDQoNCjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT4NCg0KIyMgUm91dGluZSBNTzINCg0KIyMjIFNjYWxpbmcgcHJlZGljdG9ycw0KDQpIZXJlIHdlIHNjYWxlIG91ciBwcmVkaWN0b3JzIGZvciB0aGUgbW9kZWwuIFdlIGhhdmUgZmlyc3QgYXBwbGllZCBhbiBsb2cgdHJhbnNmb3JtYXRpb24gdG8gbWFzcywgc28gaXRzIGRpcmVjdGx5IGludGVycHJldGFibGUgYXMgdGhlIG1hc3Mtc2NhbGluZyBleHBvbmVudCwganVzdCBsaWtlIGluIG1ldGFib2xpYyB0aGVvcnkuDQoNCmBgYHtyfQ0Kc2NhbGVfbGlzdCA8LSBjKCJ0ZW1wIiwgIm9yZGVyIiwgImxvZ19tYXNzIikgDQoNCnNsb3BlX3RpZHlfc21yIDwtIHNsb3BlX3RpZHlfc21yICU+JQ0KICBkcGx5cjo6bXV0YXRlKGxvZ19tYXNzID0gbG9nKG1hc3MpLA0KICAgICAgICAgICAgICAgIGFjcm9zcyhhbGxfb2Yoc2NhbGVfbGlzdCksIH4gc2NhbGUoLngsIGNlbnRlciA9IFRSVUUsIHNjYWxlID0gRkFMU0UpLA0KICAgICAgICAgICAgICAgICAgICAgICAubmFtZXMgPSAiey5jb2x9X2MiKSwNCiAgICAgICAgICAgICAgICBsaWdodF9kYXJrX2MgPSBpZl9lbHNlKGxpZ2h0X2RhcmsgPT0gImxpZ2h0IiwgMC41LCAtMC41KSkNCmBgYA0KDQpTdW1tYXJ5IG9mIHByZWRpY3RvcnMgdXNlZCBpbiB0aGUgbW9kZWwgYmVsb3cNCg0KYGBge3J9DQpzbG9wZV90aWR5X3NtciAlPiUNCiAgZHBseXI6Om11dGF0ZShjeWNsZSA9IGFzLm51bWVyaWMoY3ljbGUpKSAlPiUgDQogIGRwbHlyOjpyZWZyYW1lKHRlbXBfcmFuZ2UgPSBwYXN0ZTAocm91bmQobWluKHRlbXAsIG5hLnJtID0gVFJVRSksMiksICLigJMiLCByb3VuZChtYXgodGVtcCwgbmEucm0gPSBUUlVFKSwyKSksDQogICAgICAgICAgICBtYXNzX3JhbmdlID0gcGFzdGUwKHJvdW5kKG1pbihtYXNzLCBuYS5ybSA9IFRSVUUpLDIpLCAi4oCTIiwgcm91bmQobWF4KG1hc3MsIG5hLnJtID0gVFJVRSksMikpLA0KICAgICAgICAgIGN5Y2xlX3JhbmdlID0gcGFzdGUwKHJvdW5kKG1pbihjeWNsZSwgbmEucm0gPSBUUlVFKSwyKSwgIuKAkyIsIHJvdW5kKG1heChjeWNsZSwgbmEucm0gPSBUUlVFKSwyKSksDQogICAgICAgICAgbnVtYmVyX2Zpc2ggPSBsZW5ndGgodW5pcXVlKGlkKSkgIA0KICAgICAgICAgICkgJT4lIA0KICBndCgpDQpgYGANCg0KIyMjIE1vZGVsIHN0cnVjdHVyZQ0KDQpIZXJlIHdlIHdpbGwgdXNlIGEgQmF5ZXNpYW4gR2VuZXJhbGlzZWQgTGluZWFyIE1peGVkIE1vZGVsIChHTE1NKSB3aXRoIGEgR2FtbWEgZGlzdHJpYnV0aW9uIGFuZCBhIGxvZyBsaW5rLCB3aGVyZSB0aGUgc2hhcGUgcGFyYW1ldGVyICjOsSkgaXMgYWxzbyBtb2RlbGxlZCBhcyBhIGZ1bmN0aW9uIG9mIHByZWRpY3RvcnMuIFRoaXMgbW9kZWxzIE1PPHN1Yj4yPC9zdWI+IGJ5IHNhbGluaXR5IGR1cmluZyB0aGUgU01SIHBoYXNlIHRvIHNlZSBpZiB0aGUgZmlzaCBoZWxkIGF0IGRpZmZlcmVudCBzYWxpbml0aWVzIGhhdmUgZGlmZmVyZW50IFJNUnMuIFdlIGhhdmUgYWxzbyBhZGRlZCBhIGZldyBzY2FsZWQgcHJlZGljdG9ycywgdGhhdCBtYXkgaGVscCBkZXNjcmliZSB2YXJpYXRpb24gaW4gdGhlIGRhdGEsIHN1Y2ggYXMgbWFzcyAoZzsgMC4yMS0tMS42KSB0ZW1wZXJhdHVyZSAowrBDOyAxMy44NC0tMTQuMzgpLCBjeWNsZSBvcmRlciAoNS0tMjcpLCBhbmQgbGlnaHQvZGFyayBjeWNsZSAobGlnaHQgb3IgZGFyazsgbGlnaHQgYmV0d2VlbiAwNzowMDowMCBhbmQgMTk6MDA6MDApLCB3ZSBhbHNvIGluY2x1ZGUgYSByYW5kb20gZWZmZWN0IGZvciBmaXNoIGlkIHRvIGFjY291bnQgZm9yIG11bHRpcGxlIE1PPHN1Yj4yPC9zdWI+IG1lYXN1cmVzIG9uIGVhY2ggZmlzaCAoMS0tNTgpLiBXZSBhbGxvd2VkIHRoZSB0aGUgc2hhcGUgcGFyYW1ldGVyICjOsSkgdG8gdmFyeSBhcyBhIGZ1bmN0aW9uIG9mIHNvbWUgb2YgdGhlIHByZWRpY3RvcnMgKGUuZy4gc2FsaW5pdHlfZ3JvdXAsIG9yZGVyX3opIHRvIGltcHJvdmUgZml0Lg0KDQpgYGB7cn0NCm1vMl9nYW1tYV9iZiA8LSBiZihNTzIgfiB0ZW1wX2MgKyANCiAgICAgICAgICAgICAgICAgICAgIG9yZGVyX2MgICsgDQogICAgICAgICAgICAgICAgICAgICBsaWdodF9kYXJrX2MgKyANCiAgICAgICAgICAgICAgICAgICAgIGxvZ19tYXNzX2MgKyANCiAgICAgICAgICAgICAgICAgICAgIHNhbGluaXR5X2dyb3VwICsgKDF8aWQpLA0KICAgICAgICAgICAgICAgICAgIHNoYXBlIH4gc2FsaW5pdHlfZ3JvdXAgKyANCiAgICAgICAgICAgICAgICAgICAgIG9yZGVyX2MsDQogICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gR2FtbWEobGluayA9ICJsb2ciKSkNCmBgYA0KDQojIyMgUHJpb3Igc2VsZWN0aW9uDQoNClRoZXNlIGFyZSB0aGUgZGVmYXVsdCBwcmlvcnMuIFdlIHdpbGwgdXNlIHRoZXNlLg0KDQpgYGB7cn0NCmRlZmF1bHRfcHJpb3IgPC0gZ2V0X3ByaW9yKG1vMl9nYW1tYV9iZiwgZGF0YSA9IHNsb3BlX3RpZHlfc21yLCBmYW1pbHkgPSBHYW1tYShsaW5rID0gImxvZyIpKQ0KZGVmYXVsdF9wcmlvciAlPiUgDQogIGd0KCkNCmBgYA0KDQojIyMgUnVuIG1vZGVsDQoNCkhlcmUgd2UgcnVuIHRoZSBtb2RlbCwgSSBoYXZlIGhhc2hlZCB0aGlzIG91dCBiZWNhdXNlIEkgaGF2ZSBzYXZlZCB0aGUgbW9kZWwgZm9yIHF1aWNrIHJlbG9hZGluZy4NCg0K4o+t77iPICoqU2tpcCB0aGlzIHN0ZXAqKiBpZiB5b3UgaGF2ZSBkb3dubG9hZGVkIHRoZSBzYXZlZCBtb2RlbCBgbW8yX21vZF9nYW1tYS5yZHNgIGZyb20gR2l0SHViIChvciBwdWxsZWQgdGhlIGVudGlyZSBHaXRIdWIgcHJvamVjdCkNCg0KYGBge3IsIGVjaG89RkFMU0V9DQojIG1vMl9tb2RfZ2FtbWEgPC0gYnJtKG1vMl9nYW1tYV9iZiwNCiMgICAgICAgICAgICAgICAgZGF0YSA9IHNsb3BlX3RpZHlfc21yLA0KIyAgICAgICAgICAgICAgICBjb3JlcyA9IDQsDQojICAgICAgICAgICAgICAgIGNoYWlucyA9IDQsDQojICAgICAgICAgICAgICAgIHByaW9yID0gZGVmYXVsdF9wcmlvciwNCiMgICAgICAgICAgICAgICAgd2FybXVwID0gMTAwMCwNCiMgICAgICAgICAgICAgICAgc2VlZCA9IDE0MzAxOSwNCiMgICAgICAgICAgICAgICAgdGhpbiA9IDIsDQojICAgICAgICAgICAgICAgIGl0ZXIgPSA4MDAwLA0KIyAgICAgICAgICAgICAgICBzYXZlX3BhcnMgPSBzYXZlX3BhcnMoYWxsPVRSVUUpLA0KIyAgICAgICAgICAgICAgICBzYW1wbGVfcHJpb3IgPSBUUlVFLA0KIyAgICAgICAgICAgICAgICBmaWxlID0gcGFzdGUwKG91dHB1dF9tb2RzX3dkLCAnLi9tbzJfbW9kX2dhbW1hJykpDQojIHByaW50KCJNb2RlbCBjb21wbGV0ZSIpDQpgYGANCg0KSGVyZSB3ZSByZWxvYWQgdGhlIG1vZGVsDQoNCmBgYHtyfQ0KbW8yX21vZF9nYW1tYSA8LSAgcmVhZFJEUyhmaWxlID0gcGFzdGUwKG91dHB1dF9tb2RzX3dkLCAnLi9tbzJfbW9kX2dhbW1hLnJkcycpKQ0KYGBgDQoNCiMjIyBNb2RlbCBkaWFnbm9zdGljcw0KDQpDaGVja2luZyBtb2RlbCBjb252ZXJnZW5jZQ0KDQpgYGB7cn0NCmNvbG9yX3NjaGVtZV9zZXQoInJlZCIpDQpwbG90KG1vMl9tb2RfZ2FtbWEsIGFzayA9IEYpDQpgYGANCg0KQ2hlY2tpbmcgcmhhdCBhcmUgZXF1YWwgdG8gb25lDQoNCmBgYHtyfQ0Kc3VtbWFyeShtbzJfbW9kX2dhbW1hKQ0KYGBgDQoNClVzaW5nIGxlYXZlIG9uZSBvdXQgKGxvbykgbWVhc3VyZSBvZiBmaXQsIHRoZSBtb2RlbCBhcHBlYXJzIHRvIHByZWZvcm0gd2VsbCwgYWxsLCBidXQgb25lIFBhcmV0byBrIGVzdGltYXRlcyBhcmUgZ29vZCAoayBcPCAwLjcpDQoNCmBgYHtyfQ0KbG9vKG1vMl9tb2RfZ2FtbWEpDQpgYGANCg0KTW9kZWwgcHJlZGljdGlvbnMgZ2VuZXJhbGx5IGFsaWduIHdpdGggdGhlIG9ic2VydmVkIGRhdGENCg0KYGBge3J9DQpjb2xvcl9zY2hlbWVfc2V0KCJyZWQiKQ0KcCA8LSBwcF9jaGVjayhtbzJfbW9kX2dhbW1hLCB0eXBlID0gImRlbnNfb3ZlcmxheSIpDQpwDQpgYGANCg0KIyMjIPCfk4ggUmVzdWx0cw0KDQpXZSBkaWQgbm90IHNlZSBhIG1lYW5pbmdmdWwgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSByb3V0aW5lIG1ldGFib2xpYyByYXRlIGZvciBmaXNoIGZyb20gdGhlIHR3byBzYWxpbml0eSB0cmVhdG1lbnRzLg0KDQojIyMjIFRhYmxlIFMxDQoNCioqVGFibGUgUzEqKjogRml4ZWQgZWZmZWN0IEVzdGltYXRlcyAozrIpIGFuZCA5NSUgQ3JlZGlibGUgSW50ZXJ2YWxzICg5NSUgQ0kpDQoNCmBgYHtyfQ0KbW9kZWxfZXN0IDwtIGZpeGVmKG1vMl9tb2RfZ2FtbWEsIHByb2JzID0gYygwLjAyNSwgMC45NzUpKSAlPiUgDQogIGFzLmRhdGEuZnJhbWUoKSAlPiUgDQogIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKHZhciA9ICJQcmVkaWN0b3IiKSAlPiUgDQogIGRwbHlyOjptdXRhdGUoJ86yJyA9IHJvdW5kKEVzdGltYXRlLCAzKSwNCiAgICAgICAgICAgICAgICBRMi41ID0gcm91bmQoUTIuNSwgMyksDQogICAgICAgICAgICAgICAgUTk3LjUgPSByb3VuZChROTcuNSwgMyksDQogICAgICAgICAgICAgICAgJzk1JSBDSScgPSBwYXN0ZTAoIlsiLCBRMi41LCAiLCAiLCBROTcuNSwgIl0iKSkNCg0KbW9kZWxfZXN0ICU+JSANCiAgZHBseXI6OnNlbGVjdChQcmVkaWN0b3IsICfOsicsICc5NSUgQ0knKSAlPiUgDQogIGd0KCkNCmBgYA0KDQpMb29raW5nIGF0IHRoZSBtYXJnaW5hbCBtZWFuIE1PMiBmb3IgZWFjaCBzYWxpbml0eSB0cmVhdG1lbnQNCg0KYGBge3J9DQplbV9yZXN1bHRzIDwtIGVtbWVhbnMobW8yX21vZF9nYW1tYSwgfiBzYWxpbml0eV9ncm91cCkgDQoNCmVtX3Jlc3VsdHNfZGYgPC0gZW1fcmVzdWx0cyAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHJvdW5kKGV4cCguKSwzKSkpDQoNCmVtX3Jlc3VsdHNfZGYgJT4lIA0KICBndCgpDQpgYGANCg0KVGhlc2UgYXJlIHRoZSBlc3RpbWF0ZWQgbWVhbiBjb25zdHJhc3QsIHdlIGhhdmUgZXhwb25lbnRpYXRlZCB0aGUgbG9nIGVzdGltYXRlIHRvIGdldCB0aGUgZm9sZC1jaGFuZ2UuIFRoaXMgbWVhbnMgdGhlIG1vZGVsIHByZWRpY3RzIHRoYXQgc2FpbGlhbnR5IGdyb3VwIDAgaGFzIFx+MTIlIGhpZ2hlciBtZXRhYm9saWMgcmF0ZSB0aGFuIGdyb3VwIDkgKDEuMTIpLS0tYnV0IHRoaXMgZGlmZmVyZW5jZSBpcyBub3QgY3JlZGlibGUsIGJlY2F1c2UgdGhlIGludGVydmFsIGZvciB0aGF0IGRpZmZlcmVuY2UgaW5jbHVkZXMgbm8gZGlmZmVyZW5jZSAoaS5lLiBhIHJhdGlvIG9mIDEuMCkuDQoNCmBgYHtyfQ0KY29udHJhc3RfcmVzdWx0cyA8LSBjb250cmFzdChlbV9yZXN1bHRzLCBtZXRob2QgPSAicGFpcndpc2UiKQ0KDQpjb250cmFzdF9yZXN1bHRzX2RmIDwtICBjb250cmFzdF9yZXN1bHRzICU+JSANCiAgYXMuZGF0YS5mcmFtZSgpICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHJvdW5kKGV4cCguKSwyKSkpDQoNCmNvbnRyYXN0X3Jlc3VsdHNfZGYgJT4lIA0KICBndCgpDQpgYGANCg0KRUVNIGNvbnRyYXN0cyBmb3IgdGhlIHR3byBsaWdodCBwaGFzZXMsIHdoZXJlIC0wLjUgaXMgZGFyaywgYW5kIDAuNSBpcyBsaWdodA0KDQpgYGB7cn0NCmVtX3Jlc3VsdHMgPC0gZW1tZWFucyhtbzJfbW9kX2dhbW1hLCB+IGxpZ2h0X2RhcmtfYywNCiAgICAgICAgICAgICAgICAgICAgICAgYXQgPSBsaXN0KGxpZ2h0X2RhcmtfYyA9IGMoMC41LCAtMC41KSkpDQoNCmNvbnRyYXN0X3Jlc3VsdHMgPC0gY29udHJhc3QoZW1fcmVzdWx0cywgbWV0aG9kID0gInBhaXJ3aXNlIiwgLnJldiA9IFRSVUUpDQoNCmNvbnRyYXN0X3Jlc3VsdHNfZGYgPC0gIGNvbnRyYXN0X3Jlc3VsdHMgJT4lIA0KICBhcy5kYXRhLmZyYW1lKCkgJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH4gcm91bmQoZXhwKC4pLDIpKSkNCg0KY29udHJhc3RfcmVzdWx0c19kZiAlPiUgDQogIGd0KCkNCmBgYA0KDQpIZXJlIHdlIHdlIGNhbGN1bGF0ZSB0aGUgbW9kZWwtZXN0aW1hdGVkIG1hcmdpbmFsIG1lYW5zIGZvciBNTzIgZm9yIGEgdW5pdCBpbmNyZWFzZSBpbiBtYXNzIGFuZCB0cmFuc2Zvcm0gdGhpcyBvbnRvIGEgZm9sZC1jaGFuZ2Ugc2NhbGUuIFdoZXJlIGxvZyhtYXNzKSBoYXMgYmUgY2VudGVyZWQsIGEgdmF1bGUgb2YgMCByZXByZXNlbnRzIHRoZSBtZWFuIG1hc3Mgb2YgZmlzaCwgYW5kIDEgY29ycmVzcG9uZHMgdG8gYSBmaXNoIHdpdGggbG9nKG1hc3MpID0gMSB1bml0IGFib3ZlIHRoZSBtZWFuIChpLmUuIDIuNyB0aW1lcyBsYXJnZSkuDQoNCmxvZyhtYXNzPHN1Yj4yPC9zdWI+KSA9IGxvZyhtYXNzPHN1Yj4xPC9zdWI+KSsxDQoNCklmIHlvdSBleHBvbmVudGlhdGUgYm90aCBzaWRlczoNCg0KbWFzczxzdWI+Mjwvc3ViPiA9IG1hc3M8c3ViPjE8L3N1Yj4geCBleHAoMSkNCg0KbWFzczxzdWI+Mjwvc3ViPiDiiYggbWFzczxzdWI+MTwvc3ViPiB4IDIuNzE4DQoNCmBgYHtyfQ0KZW1fbWFzcyA8LSBlbW1lYW5zKG1vMl9tb2RfZ2FtbWEsIH4gbG9nX21hc3NfYywgYXQgPSBsaXN0KGxvZ19tYXNzX2MgPSBjKDAsIDEpKSkNCg0KIyBHZXQgdGhlIGNvbnRyYXN0IChkaWZmZXJlbmNlIGluIGxvZyBNT+KCgiksIHRoZW4gYmFjay10cmFuc2Zvcm0NCmNvbnRyYXN0KGVtX21hc3MsIG1ldGhvZCA9ICJyZXZwYWlyd2lzZSIpICU+JQ0KICBhcy5kYXRhLmZyYW1lKCkgJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIGV4cCkpICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHJvdW5kKC4sIDIpKSkgJT4lDQogIGd0KCkNCmBgYA0KDQpQdWxsaW5nIHRoZSBlbW1lYW5zIGRyYXdzIGZvciBvdXIgcGxvdA0KDQpgYGB7cn0NCmVtbWVhbnNfZHJhd3Nfcm1yIDwtIG1vMl9tb2RfZ2FtbWEgJT4lDQogIGVtbWVhbnMofiBzYWxpbml0eV9ncm91cCkgJT4lDQogIGdhdGhlcl9lbW1lYW5zX2RyYXdzKCkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKC52YWx1ZSA9ICBleHAoLnZhbHVlKSwNCiAgICAgICAgICAgICAgICBzYWxpbml0eV9ncm91cCA9IGFzLmNoYXJhY3RlcihzYWxpbml0eV9ncm91cCkpDQoNCmVtbWVhbnNfY29udHJhc3RfZHJhd3Nfcm1yICA8LSAgbW8yX21vZF9nYW1tYSAlPiUNCiAgZW1tZWFucyh+IHNhbGluaXR5X2dyb3VwKSAlPiUNCiAgY29udHJhc3QobWV0aG9kID0gInBhaXJ3aXNlIikgJT4lDQogIGdhdGhlcl9lbW1lYW5zX2RyYXdzKCkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKC52YWx1ZSA9ICBleHAoLnZhbHVlKSkNCmBgYA0KDQojIyMjIEZpZ3VyZSAxYQ0KDQoqKipOT1RFOiBUaGlzIHBsb3QgaXMgaW4gdGhlIG1haW4gdGV4dCBvZiB0aGUgbWFudXNjcmlwdCwgd2hpY2ggaXMgd2F5IGl0IGlzIGNhbGxlZCBGaWd1cmUgMWEgKG5vdCBGaWd1cmUgU2kpKioqDQoNCmBgYHtyfQ0KZmlnXzFhIDwtIGdncGxvdCgpICsNCiAgZ2VvbV92aW9saW4oZGF0YSA9IHNsb3BlX3RpZHlfc21yLA0KICAgICAgICAgICAgICBhZXMoeCA9IHNhbGluaXR5X2dyb3VwLCB5ID0gTU8yLCBmaWxsID0gc2FsaW5pdHlfZ3JvdXApLA0KICAgICAgICAgICAgICBjb2xvciA9IE5BLCBhbHBoYSA9IDAuMikgKw0KICBnZW9tX2ppdHRlcihkYXRhID0gc2xvcGVfdGlkeV9zbXIsDQogICAgICAgICAgICAgIGFlcyh4ID0gc2FsaW5pdHlfZ3JvdXAsIHkgPSBNTzIsIGZpbGwgPSBzYWxpbml0eV9ncm91cCksDQogICAgICAgICAgICAgIHNoYXBlID0gMjEsIHdpZHRoID0gMC4zLCBzaXplID0gMSwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuMSkgKw0KICBnZW9tX3BvaW50KGRhdGEgPSBtZWFuX21vMl9zYWxpbml0eSwNCiAgICAgICAgICAgICBhZXMoeCA9IHNhbGluaXR5X2dyb3VwLCB5ID0gbWVhbl9tbzIsIGZpbGwgPSBzYWxpbml0eV9ncm91cCksDQogICAgICAgICAgICAgc2l6ZSA9IDQsIGFscGhhID0gMSwgc3Ryb2tlID0gMiwgY29sb3IgPSAiYmxhY2siLCBzaGFwZSA9IDIxLA0KICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fbnVkZ2UoeCA9IDAuMDUpKSArDQogIHN0YXRfcG9pbnRpbnRlcnZhbChkYXRhID0gZW1tZWFuc19kcmF3c19ybXIsIA0KICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBzYWxpbml0eV9ncm91cCwgeSA9IC52YWx1ZSksDQogICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAiZ3JleSIsIHBvaW50X2ludGVydmFsID0gIm1lYW5fcWkiLCAud2lkdGggPSAwLjk1LCBzaGFwZSA9IDIxLCAgc3Ryb2tlID0gMiwgcG9pbnRfc2l6ZSA9IDQsIGFscGhhID0gMSwNCiAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fbnVkZ2UoeCA9IC0wLjA1KSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLjAwLCAwLjM1KSkgKyAgIyDwn5GIIFNldCB5LWF4aXMgcmFuZ2UgaGVyZQ0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjNEI1MzIwIiwgIiMwMDAwODAiKSkgKw0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoIiM0QjUzMjAiLCAiIzAwMDA4MCIpKSArDQogIHRoZW1lKA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGNvbG91ciA9ICJibGFjayIsIGZpbGwgPSBOQSwgbGluZXdpZHRoID0gMSksDQogICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIiwgY29sb3VyID0gTkEpLA0KICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIiwgY29sb3VyID0gTkEpDQogICkgKw0KICBsYWJzKA0KICAgIHN1YnRpdGxlID0gIiIsDQogICAgeCA9ICJTYWxpbml0eSBncm91cCAocHB0KSIsDQogICAgeSA9ICJSb3V0aW5lIE1PMiAobWcgTzIgZy9oKSINCiAgKQ0KDQpmaWdfMWENCmBgYA0KDQoqKkZpZ3VyZSAxYToqKiBSb3V0aW5lIG1ldGFib2xpYyByYXRlIChpLmUuIE1PPHN1Yj4yPC9zdWI+IChtZ14tMV4gTzxzdWI+Mjwvc3ViPiBoXi0xXikgbWVhc3VyZWQgZHVyaW5nIFNNUiBtZWFzc3VybWVudHMpIHBsb3R0ZWQgYnkgc2FsaW5pdHkgdHJlYXRtZW50LiBUaGUgc21hbGwgdHJhbnNwYXJlbnQgcG9pbnRzIGFyZSB0aGUgb2JzZXJ2ZWQgdmFsdWVzLCB0aGUgc2hhZGVkIGFyZWEgYmVoaW5kIHRoZSBwb2ludHMgaXMgdGhlIGEga2VybmVsIGRlbnNpdHkgb2YgdGhlIG9ic2VydmVkIGRhdGEsIHRoZSBsYXJnZSBjb2xvdXJlZCBwb2ludCAodG8gdGhlIHJpZ2h0KSBpcyB0aGUgb2JzZXJ2ZWQgbWVhbiwgdGhlIGxhcmdlIGdyZXkgcG9pbnQgd2l0aCBlcnJvciBiYXJzICh0byB0aGUgbGVmdCkgaXMgdGhlIG1vZGVsIGVzdGltYXRlZCBtYXJnaW5hbCBtZWFuIChlZW1lYW4pIDk1JSBDcmVkaWJsZSBJbnRlcnZhbHMgKDk1JSBDSSkuDQoNCmBgYHtyfQ0KIyBnZ3NhdmUoZmlsZW5hbWUgPSBwYXN0ZTAob3V0cHV0X2ZpZ193ZCwgIi4vbXNfZmlndXJlcy4vZmlndXJlLTFhLnBkZiIpLA0KIyAgICAgICAgcGxvdCA9IGZpZ18xYSwNCiMgICAgICAgIHdpZHRoID0gMjEwLzIsDQojICAgICAgICBoZWlnaHQgPSAyOTcvMiwgICMgU3BlY2lmeSB0aGUgaGVpZ2h0IG9mIHRoZSBwbG90DQojICAgICAgICB1bml0cyA9ICJtbSIpDQpgYGANCg0KDQpUaGVyZSB3YXMgbW9kZXJhdGUgYnV0IG1lYW5pbmdmdWwgdmFyaWF0aW9uIGluIFJNUiBiZXR3ZWVuIGluZGl2aWR1YWxzLCBldmVuIGFmdGVyIGFjY291bnRpbmcgZm9yIG1hc3MsIHRlbXBlcmF0dXJlLCBzYWxpbml0eSwgYW5kIGxpZ2h0IHBoYXNlLiBUaGUgZXN0aW1hdGVkIHN0YW5kYXJkIGRldmlhdGlvbiBvZiBpbmRpdmlkdWFsIFJNUiB3YXMgMC4zMSBbMC4yNiB0byAwLjM4XSwgaW5kaWNhdGluZyB0aGF0IGluZGl2aWR1YWwgaWRlbnRpdHkgZXhwbGFpbmVkIGEgbWVhbmluZ2Z1bCBwcm9wb3J0aW9uIG9mIHRoZSBvYnNlcnZlZCB2YXJpYXRpb24uDQoNCmBgYHtyfQ0KcmFuZG9tX2VmZmVjdCA8LSBzdW1tYXJ5KG1vMl9tb2RfZ2FtbWEpJHJhbmRvbSRpZA0KcmFuZG9tX2VmZmVjdCAlPiUgDQogIGd0KCkNCmBgYA0KDQojIyBTTVINCg0KIyMjIEZvcm1hdGluZyBhbmQgc2NhbGluZyBkYXRhDQoNCkhlcmUgd2UgYXJlIGZpbHRlcmluZyB0aGUgZGF0YSBmcmFtZSB0byBoYXZlIG9ubHkgbWVhc3VyZSBwZXIgZmlzaCBmb3IgdGhlIFNNUiBlc3RpbWF0ZQ0KDQpgYGB7cn0NCnNjYWxlX2xpc3QgPC0gYygidGVtcF9tZWFuIiwgImxvZ19tYXNzIiwgImN5Y2xlcyIpDQoNCnNtciA8LSBzbG9wZV90aWR5X3NtciAlPiUNCiAgZHBseXI6Omdyb3VwX2J5KGlkKSAlPiUgDQogIGRwbHlyOjpyZWZyYW1lKHRlbXBfbWVhbiA9IG1lYW4odGVtcCksDQogICAgICAgICAgICAgICAgIGxvZ19tYXNzID0gbG9nX21hc3NbMV0sDQogICAgICAgICAgICAgICAgIG1hc3MgPSBtYXNzWzFdLA0KICAgICAgICAgICAgICAgICBTTVIgPSBTTVJbMV0sDQogICAgICAgICAgICAgICAgIHNhbGluaXR5X2dyb3VwID0gc2FsaW5pdHlfZ3JvdXBbMV0sDQogICAgICAgICAgICAgICAgIGN5Y2xlcyA9IGxlbmd0aChvcmRlcikpICU+JSANCiAgZHBseXI6Om11dGF0ZShhY3Jvc3MoYWxsX29mKHNjYWxlX2xpc3QpLCB+IHNjYWxlKC54LCBjZW50ZXIgPSBUUlVFLCBzY2FsZSA9IEZBTFNFKSwNCiAgICAgICAgICAgICAgICAgICAgICAgLm5hbWVzID0gInsuY29sfV9jIikpDQpgYGANCg0KU3VtbWFyeSBvZiBwcmVkaWN0b3JzIHVzZWQgaW4gdGhlIG1vZGVsIGJlbG93DQoNCmBgYHtyfQ0Kc21yICU+JQ0KICBkcGx5cjo6cmVmcmFtZSh0ZW1wX3JhbmdlID0gcGFzdGUwKHJvdW5kKG1pbih0ZW1wX21lYW4sIG5hLnJtID0gVFJVRSksMiksICLigJMiLCByb3VuZChtYXgodGVtcF9tZWFuLCBuYS5ybSA9IFRSVUUpLDIpKSwNCiAgICAgICAgICAgIG1hc3NfcmFuZ2UgPSBwYXN0ZTAocm91bmQobWluKG1hc3MsIG5hLnJtID0gVFJVRSksMiksICLigJMiLCByb3VuZChtYXgobWFzcywgbmEucm0gPSBUUlVFKSwyKSksDQogICAgICAgICAgY3ljbGVfcmFuZ2UgPSBwYXN0ZTAocm91bmQobWluKGN5Y2xlcywgbmEucm0gPSBUUlVFKSwyKSwgIuKAkyIsIHJvdW5kKG1heChjeWNsZXMsIG5hLnJtID0gVFJVRSksMikpLA0KICAgICAgICAgIG51bWJlcl9maXNoID0gbGVuZ3RoKHVuaXF1ZShpZCkpICANCiAgICAgICAgICApICU+JSANCiAgZ3QoKQ0KYGBgDQoNCiMjIyBNb2RlbCBzdHJ1Y3R1cmUNCg0KSGVyZSB3ZSB3aWxsIHVzZSBhIEJheWVzaWFuIEdlbmVyYWxpc2VkIExpbmVhciBNaXhlZCBNb2RlbCAoR0xNTSkgd2l0aCBhIEdhbW1hIGRpc3RyaWJ1dGlvbiBhbmQgYSBsb2cgbGluayBgR2FtbWEobGluayA9ICJsb2ciKWAsIHdoZXJlIHRoZSBzaGFwZSBwYXJhbWV0ZXIgKM6xKSBpcyBhbHNvIG1vZGVsbGVkIGFzIGEgZnVuY3Rpb24gb2YgdGhlIHNhbGluaXR5IGdyb3VwLCBgc2hhcGUgfiBzYWxpbml0eV9ncm91cGAuIFRoaXMgbW9kZWxzIE1PMiBieSBzYWxpbml0eSBkdXJpbmcgdGhlIFNNUiBwaGFzZSB0byBzZWUgaWYgdGhlIGZpc2ggaGVsZCBhdCBkaWZmZXJlbnQgc2FsaW5pdGllcyBoYXZlIGRpZmZlcmVudCBTTVJzLiBXZSBoYXZlIGFsc28gYWRkZWQgYSBmZXcgc2NhbGVkIHByZWRpY3RvcnMsIHRoYXQgbWF5IGhlbHAgZGVzY3JpYmUgdmFyaWF0aW9uIGluIHRoZSBkYXRhLCBzdWNoIGFzIGZpc2ggbWFzcyAoZzsgMC4yMS0tMS42KSBtZWFuIHRlbXBlcmF0dXJlICjCsEM7IDEzLjg0MS0tMTQuMjc3KSwgYW5kIHRoZSBudW1iZXIgb2YgY3ljbGVzIG92ZXIgd2hpY2ggU01SIHdhcyBlc3RpbWF0ZWQgKDEtLTIzKS4gV2UgYWxsb3dlZCB0aGUgdGhlIHNoYXBlIHBhcmFtZXRlciAozrEpIHRvIHZhcnkgYXMgYSBmdW5jdGlvbiBvZiBzYWxpbml0eV9ncm91cCB0byBpbXByb3ZlIGZpdC4NCg0KYGBge3J9DQpzbXJfZ2FtbWFfYmYgPC0gYmYoU01SIH4gdGVtcF9tZWFuX2MgKyANCiAgICAgICAgICAgICAgICAgIGN5Y2xlc19jICArDQogICAgICAgICAgICAgICAgICBsb2dfbWFzc19jICsgDQogICAgICAgICAgICAgICAgICBzYWxpbml0eV9ncm91cCwNCiAgICAgICAgICAgICAgICAgIHNoYXBlIH4gc2FsaW5pdHlfZ3JvdXAsDQogICAgICAgICAgICAgICAgICBmYW1pbHkgPSBHYW1tYShsaW5rID0gImxvZyIpKQ0KYGBgDQoNCiMjIyBQcmlvciBzZWxlY3Rpb24NCg0KVGhlc2UgYXJlIHRoZSBkZWZhdWx0IHByaW9ycyBmb3IgdGhlIG1vZGVsLiBXZSB3aWxsIHVzZSB0aGVzZS4NCg0KYGBge3J9DQpwcmlvcnNfZGVmYXVsdCA8LSBnZXRfcHJpb3Ioc21yX2dhbW1hX2JmLCBkYXRhID0gc21yLCBmYW1pbHkgPSBHYW1tYShsaW5rID0gImxvZyIpKQ0KcHJpb3JzX2RlZmF1bHQgJT4lIA0KICBndCgpDQpgYGANCg0KIyMjIFJ1biBtb2RlbA0KDQpIZXJlIHdlIHJ1biB0aGUgbW9kZWwsIEkgaGF2ZSBoYXNoZWQgdGhpcyBvdXQgYmVjYXVzZSBJIGhhdmUgc2F2ZWQgdGhlIG1vZGVsIGZvciBxdWljayByZWxvYWRpbmcuDQoNCuKPre+4jyAqKlNraXAgdGhpcyBzdGVwKiogaWYgeW91IGhhdmUgZG93bmxvYWRlZCB0aGUgc2F2ZWQgbW9kZWwgJ3Ntcl9tb2RfZ2FtbWEucmRzJw0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCiMgc21yX21vZF9nYW1tYV9jIDwtIGJybShzbXJfZ2FtbWFfYmYsDQojICAgICAgICAgICAgICAgIGRhdGEgPSBzbXIsDQojICAgICAgICAgICAgICAgIGNvcmVzID0gNCwNCiMgICAgICAgICAgICAgICAgY2hhaW5zID0gNCwNCiMgICAgICAgICAgICAgICAgcHJpb3IgPSBwcmlvcnNfZGVmYXVsdCwNCiMgICAgICAgICAgICAgICAgd2FybXVwID0gMTAwMCwNCiMgICAgICAgICAgICAgICAgc2VlZCA9IDE0MzAxOSwNCiMgICAgICAgICAgICAgICAgdGhpbiA9IDIsDQojICAgICAgICAgICAgICAgIGl0ZXIgPSA4MDAwLA0KIyAgICAgICAgICAgICAgICBzYXZlX3BhcnMgPSBzYXZlX3BhcnMoYWxsPVRSVUUpLA0KIyAgICAgICAgICAgICAgICBzYW1wbGVfcHJpb3IgPSBUUlVFLA0KIyAgICAgICAgICAgICAgICBmaWxlID0gcGFzdGUwKG91dHB1dF9tb2RzX3dkLCAnLi9zbXJfbW9kX2dhbW1hJykpDQojIHByaW50KCJNb2RlbCBjb21wbGV0ZSIpDQpgYGANCg0KSGVyZSB3ZSByZWxvYWQgdGhlIG1vZGVsDQoNCmBgYHtyfQ0Kc21yX21vZF9nYW1tYSA8LSAgcmVhZFJEUyhmaWxlID0gcGFzdGUwKG91dHB1dF9tb2RzX3dkLCAnLi9zbXJfbW9kX2dhbW1hLnJkcycpKQ0KYGBgDQoNCiMjIyBNb2RlbCBkaWFnbm9zdGljcw0KDQpDaGVja2luZyBtb2RlbCBjb252ZXJnZW5jZQ0KDQpgYGB7cn0NCmNvbG9yX3NjaGVtZV9zZXQoInJlZCIpDQpwbG90KHNtcl9tb2RfZ2FtbWEsIGFzayA9IEYpDQpgYGANCg0KVXNpbmcgbGVhdmUgb25lIG91dCAobG9vKSBtZWFzdXJlIG9mIGZpdCwgdGhlIG1vZGVsIGFwcGVhcnMgdG8gcHJlZm9ybSB3ZWxsLCB0d28gUGFyZXRvIGsgZXN0aW1hdGVzIGZhbGxzIG91dHNpZGUgdGhlIGdvb2QgcmFuZ2UgKDAuNywgMV0NCg0KYGBge3J9DQpsb28oc21yX21vZF9nYW1tYSkNCmBgYA0KDQpNb2RlbCBwcmVkaWN0aW9ucyBnZW5lcmFsbHkgYWxpZ24gd2l0aCB0aGUgb2JzZXJ2ZWQgZGF0YSwgYnV0IHRoZXJlIGlzIGEgbG90IG9mIHVuY2VydGFpbnR5IGFyb3VuZCB0aGlzIGVzdGltYXRlLg0KDQpgYGB7cn0NCmNvbG9yX3NjaGVtZV9zZXQoInJlZCIpDQpwIDwtIHBwX2NoZWNrKHNtcl9tb2RfZ2FtbWEsIHR5cGUgPSAiZGVuc19vdmVybGF5IikNCnANCmBgYA0KDQojIyMg8J+TiCBSZXN1bHRzDQoNCldlIGRpZCBub3Qgc2VlIGEgbWVhbmluZ2Z1bCBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHJvdXRpbmUgbWV0YWJvbGljIHJhdGUgZm9yIGZpc2ggZnJvbSB0aGUgdHdvIHNhbGluaXR5IHRyZWF0bWVudHMuDQoNCiMjIyMgVGFibGUgUzINCg0KKipUYWJsZSBTMjoqKiBGaXhlZCBlZmZlY3QgRXN0aW1hdGVzICjOsikgYW5kIDk1JSBDcmVkaWJsZSBJbnRlcnZhbHMgKDk1JSBDSSkgZnJvbSBhIEJheWVzaWFuIEdlbmVyYWxpc2VkIExpbmVhciBNaXhlZCBNb2RlbCAoR0xNTSkgd2l0aCBhIEdhbW1hIGRpc3RyaWJ1dGlvbiBhbmQgYSBsb2cgbGluaw0KDQpgYGB7cn0NCm1vZGVsX2VzdCA8LSBmaXhlZihzbXJfbW9kX2dhbW1hLCBwcm9icyA9IGMoMC4wMjUsIDAuOTc1KSkgJT4lIA0KICBhcy5kYXRhLmZyYW1lKCkgJT4lIA0KICB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbih2YXIgPSAiUHJlZGljdG9yIikgJT4lIA0KICBkcGx5cjo6bXV0YXRlKCfOsicgPSByb3VuZChFc3RpbWF0ZSwgMyksDQogICAgICAgICAgICAgICAgUTIuNSA9IHJvdW5kKFEyLjUsIDMpLA0KICAgICAgICAgICAgICAgIFE5Ny41ID0gcm91bmQoUTk3LjUsIDMpLA0KICAgICAgICAgICAgICAgICc5NSUgQ0knID0gcGFzdGUwKCJbIiwgUTIuNSwgIiwgIiwgUTk3LjUsICJdIikpDQoNCm1vZGVsX2VzdCAlPiUgDQogIGRwbHlyOjpzZWxlY3QoUHJlZGljdG9yLCAnzrInLCAnOTUlIENJJykgJT4lIA0KICBndCgpDQpgYGANCg0KTG9va2luZyBhdCB0aGUgbWFyZ2luYWwgbWVhbiBkaWZmZXJlbmNlIGJldHdlZW4gc2FsaW5pdHkgZ3JvdXBzDQoNCmBgYHtyfQ0KZW1fcmVzdWx0cyA8LSBlbW1lYW5zKHNtcl9tb2RfZ2FtbWEsIH4gc2FsaW5pdHlfZ3JvdXApIA0KDQplbV9yZXN1bHRzX2RmIDwtICBlbV9yZXN1bHRzICU+JSANCiAgYXMuZGF0YS5mcmFtZSgpICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHJvdW5kKGV4cCguKSwzKSkpDQoNCg0KZW1fcmVzdWx0c19kZiAlPiUgDQogIGd0KCkNCmBgYA0KDQpgYGB7cn0NCmNvbnRyYXN0X3Jlc3VsdHNfZGYgPC0gIGNvbnRyYXN0X3Jlc3VsdHMgJT4lIA0KICBhcy5kYXRhLmZyYW1lKCkgJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH4gZXhwKC4pKSkNCg0KY29udHJhc3QoZW1fcmVzdWx0cywgbWV0aG9kID0gInBhaXJ3aXNlIikgJT4lIA0KICBhcy5kYXRhLmZyYW1lKCkgJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH4gcm91bmQoZXhwKC4pLDIpKSkgJT4lIA0KICBndCgpDQpgYGANCg0KSGVyZSB3ZSB3ZSBjYWxjdWxhdGUgdGhlIG1vZGVsLWVzdGltYXRlZCBtYXJnaW5hbCBtZWFucyBmb3IgU01SIGZvciBhIHVuaXQgaW5jcmVhc2UgaW4gbWFzcyBhbmQgdHJhbnNmb3JtIHRoaXMgb250byBhIGZvbGQtY2hhbmdlIHNjYWxlLiBXaGVyZSBsb2cobWFzcykgaGFzIGJlIGNlbnRlcmVkLCBhIHZhdWxlIG9mIDAgcmVwcmVzZW50cyB0aGUgbWVhbiBtYXNzIG9mIGZpc2gsIGFuZCAxIGNvcnJlc3BvbmRzIHRvIGEgZmlzaCB3aXRoIGxvZyhtYXNzKSA9IDEgdW5pdCBhYm92ZSB0aGUgbWVhbiAoaS5lLiAyLjcgdGltZXMgbGFyZ2UpLg0KDQpgYGB7cn0NCmVtX21hc3MgPC0gZW1tZWFucyhzbXJfbW9kX2dhbW1hLCB+IGxvZ19tYXNzX2MsIGF0ID0gbGlzdChsb2dfbWFzc19jID0gYygwLCAxKSkpDQoNCiMgR2V0IHRoZSBjb250cmFzdCAoZGlmZmVyZW5jZSBpbiBsb2cgTU/igoIpLCB0aGVuIGJhY2stdHJhbnNmb3JtDQpjb250cmFzdChlbV9tYXNzLCBtZXRob2QgPSAicmV2cGFpcndpc2UiKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCBleHApKSAlPiUNCiAgbXV0YXRlKGFjcm9zcyh3aGVyZShpcy5udW1lcmljKSwgfiByb3VuZCguLCAyKSkpICU+JQ0KICBndCgpDQpgYGANCg0KUHVsbGluZyB0aGUgZW1tZWFucyBkcmF3cyBmb3Igb3VyIHBsb3QNCg0KYGBge3J9DQplbW1lYW5zX2RyYXdfc21yIDwtIHNtcl9tb2RfZ2FtbWEgJT4lDQogIGVtbWVhbnMofiBzYWxpbml0eV9ncm91cCkgJT4lDQogIGdhdGhlcl9lbW1lYW5zX2RyYXdzKCkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKC52YWx1ZSA9ICBleHAoLnZhbHVlKSwNCiAgICAgICAgICAgICAgICBzYWxpbml0eV9ncm91cCA9IGFzLmNoYXJhY3RlcihzYWxpbml0eV9ncm91cCkpDQoNCmVtbWVhbnNfY29udHJhc3RfZHJhd3Nfc21yIDwtICBzbXJfbW9kX2dhbW1hICU+JQ0KICBlbW1lYW5zKH4gc2FsaW5pdHlfZ3JvdXApICU+JQ0KICBjb250cmFzdChtZXRob2QgPSAicGFpcndpc2UiKSAlPiUNCiAgZ2F0aGVyX2VtbWVhbnNfZHJhd3MoKSAlPiUgDQogIGRwbHlyOjptdXRhdGUoLnZhbHVlID0gIGV4cCgudmFsdWUpKQ0KYGBgDQoNCiMjIyMgRmlndXJlIDFiDQoNCioqTk9URTogVGhpcyBwbG90IGlzIGluIHRoZSBtYWluIHRleHQgb2YgdGhlIG1hbnVzY3JpcHQgd2hpY2ggaXMgd2h5IGl0IGlzIEZpZ3VyZSAxYiAobm90IEZpZ3VyZSBTaSkqKg0KDQpgYGB7cn0NCm1lYW5fc21yX3NhbGluaXR5IDwtIHNtciAlPiUNCiAgZHBseXI6Omdyb3VwX2J5KHNhbGluaXR5X2dyb3VwKSAlPiUNCiAgZHBseXI6OnJlZnJhbWUobWVhbl9TTVIgPSBtZWFuKFNNUiwgbmEucm0gPSBUUlVFKSkNCg0KDQpmaWdfMWIgPC0gZ2dwbG90KCkgKw0KICBnZW9tX3Zpb2xpbihkYXRhID0gc21yLA0KICAgICAgICAgICAgICBhZXMoeCA9IHNhbGluaXR5X2dyb3VwLCB5ID0gU01SLCBmaWxsID0gc2FsaW5pdHlfZ3JvdXApLA0KICAgICAgICAgICAgICBjb2xvciA9IE5BLCBhbHBoYSA9IDAuMikgKw0KICBnZW9tX2ppdHRlcihkYXRhID0gc21yLA0KICAgICAgICAgICAgICBhZXMoeCA9IHNhbGluaXR5X2dyb3VwLCB5ID0gU01SLCBmaWxsID0gc2FsaW5pdHlfZ3JvdXApLA0KICAgICAgICAgICAgICBzaGFwZSA9IDIxLCB3aWR0aCA9IDAuMywgc2l6ZSA9IDEsIGNvbG9yID0gImJsYWNrIiwgYWxwaGEgPSAwLjEpICsNCiAgZ2VvbV9wb2ludChkYXRhID0gbWVhbl9zbXJfc2FsaW5pdHksDQogICAgICAgICAgICAgYWVzKHggPSBzYWxpbml0eV9ncm91cCwgeSA9IG1lYW5fU01SLCBmaWxsID0gc2FsaW5pdHlfZ3JvdXApLA0KICAgICAgICAgICAgIHNpemUgPSA0LCBhbHBoYSA9IDEsIHN0cm9rZSA9IDIsIGNvbG9yID0gImJsYWNrIiwgc2hhcGUgPSAyMSwNCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX251ZGdlKHggPSAwLjA1KSkgKw0KICBzdGF0X3BvaW50aW50ZXJ2YWwoZGF0YSA9IGVtbWVhbnNfZHJhd19zbXIsDQogICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IHNhbGluaXR5X2dyb3VwLCB5ID0gLnZhbHVlKSwNCiAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9ICJncmV5IiwgcG9pbnRfaW50ZXJ2YWwgPSAibWVhbl9xaSIsIC53aWR0aCA9IDAuOTUsIHNoYXBlID0gMjEsICBzdHJva2UgPSAyLCBwb2ludF9zaXplID0gNCwgYWxwaGEgPSAxLA0KICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9udWRnZSh4ID0gLTAuMDUpKSArDQogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAuMDAsIDAuMzUpKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM0QjUzMjAiLCAiIzAwMDA4MCIpKSArICAjIEN1c3RvbSBmaWxsIGNvbG91cnMNCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCIjNEI1MzIwIiwgIiMwMDAwODAiKSkgKw0KICB0aGVtZSgNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiYmxhY2siLCBmaWxsID0gTkEsIGxpbmV3aWR0aCA9IDEpLA0KICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIsIGNvbG91ciA9IE5BKSwNCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIsIGNvbG91ciA9IE5BKQ0KICApICsNCiAgbGFicygNCiAgICBzdWJ0aXRsZSA9ICIiLA0KICAgIHggPSAiU2FsaW5pdHkgZ3JvdXAgKHBwdCkiLA0KICAgIHkgPSAiU3RhbmRhcmQgbWV0YWJvbGljIHJhdGUgKFNNUjsgbWcgTzIgZy9oKSINCiAgKQ0KDQpmaWdfMWINCmBgYA0KDQoNCioqRmlndXJlIDFiOioqIFRoZSBzdGFuZGFyZCBtZXRhYm9saWMgcmF0ZSBlc3RpbWF0ZSAobWdeLTFeIE88c3ViPjI8L3N1Yj4gaF4tMV4pIHBsb3R0ZWQgYnkgc2FsaW5pdHkgdHJlYXRtZW50LiBUaGUgc21hbGwgdHJhbnNwYXJlbnQgcG9pbnRzIGFyZSB0aGUgb2JzZXJ2ZWQgdmFsdWVzLCB0aGUgc2hhZGVkIGFyZWEgYmVoaW5kIHRoZSBwb2ludHMgaXMgdGhlIGEga2VybmVsIGRlbnNpdHkgb2YgdGhlIG9ic2VydmVkIGRhdGEsIHRoZSBsYXJnZSBjb2xvdXJlZCBwb2ludCAodG8gdGhlIHJpZ2h0KSBpcyB0aGUgb2JzZXJ2ZWQgbWVhbiwgdGhlIGxhcmdlIGdyZXkgcG9pbnQgd2l0aCBlcnJvciBiYXJzICh0byB0aGUgbGVmdCkgaXMgdGhlIG1vZGVsIGVzdGltYXRlZCBtYXJnaW5hbCBtZWFuIChlZW1lYW4pIDk1JSBDcmVkaWJsZSBJbnRlcnZhbHMgKDk1JSBDSSkuDQoNCmBgYHtyfQ0KIyBnZ3NhdmUoZmlsZW5hbWUgPSBwYXN0ZTAob3V0cHV0X2ZpZ193ZCwgIi4vbXNfZmlndXJlcy4vZmlndXJlLTFiLnBkZiIpLA0KIyAgICAgICAgcGxvdCA9IGZpZ18xYiwNCiMgICAgICAgIHdpZHRoID0gMjEwLzIsDQojICAgICAgICBoZWlnaHQgPSAyOTcvMiwgICMgU3BlY2lmeSB0aGUgaGVpZ2h0IG9mIHRoZSBwbG90DQojICAgICAgICB1bml0cyA9ICJtbSIpDQpgYGANCg0KIyMgSW5jcmVtZW50YWwgcmVncmVzc2lvbiBhbmFseXNlcw0KDQpIZXJlIHdlIGFyZSBmb2xsb3dpbmcgdGhlIG1ldGhvZHMgVXJiaW5hIGV0IGFsLiAoMjAxMileWzFdXiB3aXRoIGFuIGluY3JlbWVudGFsIHJlZ3Jlc3Npb24gYW5hbHlzZXMsIGluIG9yZGVyIHRvIGRldGVybWluZSB0aGUgYmVzdCBmaXQgZm9yIHRoZSBNTzxzdWI+Mjwvc3ViPiB2cyBPPHN1Yj4yPC9zdWI+IGRhdGENCg0KVGhpcyBhbmFseXNpcyBhcHByb2FjaCBldmFsdWF0ZXMgdGhlIHJlbGF0aXZlICdmaXQnIG9mIGVhY2ggcG9seW5vbWlhbCBvcmRlciBlcXVhdGlvbiBzdGFydGluZyBhdCB6ZXJvIGFuZCBpbmNyZWFzaW5nIHRvIHRoZSB0aGlyZCBvcmRlciwgcGVybWl0dGluZyBhIG1hdGhlbWF0aWNhbCBhc3Nlc3NtZW50IG9mIHdoZXRoZXIgZmlzaCB3ZXJlIG94eWNvbmZvcm1pbmcgb3Igb3h5cmVndWxhdG9yaW5nLiBJZiB0aGUgZGF0YSBpcyBiZXN0IGZpdHRlZC9wcmVkaWN0ZWQgYnkgYSBzaW5nbGUgbGluZWFyIHJlbGF0aW9uc2hpcCAoMV5zdF4tb3JkZXIgcG9seW5vbWlhbCkgd2l0aCBhIHBvc2l0aXZlIHNsb3BlLCB0aGlzIHdvdWxkIHN1Z2dlc3RzIHRoZSBmaXNoIHdlcmUgb3h5Y29uZm9ybWluZy4gQWx0ZXJuYXRlbHksIGlmIHRoZSByZWxhdGlvbnNoaXAgaXMgYmVzdCBtb2RlbGxlZCBieSBhIGZsYXQgcmVncmVzc2lvbiAoMF50aF4tb3JkZXIgcG9seW5vbWlhbCksIG9yIGEgaGlnaGVyIG9yZGVyIHBvbHlub21pYWwgKDJebmReIG9yIDNecmReLW9yZGVyIHBvbHlub21pYWwpIHRoZSBmaXNoIGlzIGxpa2VseSBveHlyZWd1bGF0b3JpbmcuDQoNCiMjIyBCdWlsZGluZyBCYXllc2lhbiByZWdyZXNzaW9ucw0KDQpIZXJlIHdlIGFyZSB1c2luZyBhIEJheWVzaWFuIGFwcHJvYWNoIHRvIG1vZGVsIGZpdHRpbmcgd2l0aCBicm0uIFRoZXNlIG1vZGVscyB0YWtlIGEgbG9uZyB0aW1lIHRvIHJ1biwgc28gSSBoYXZlIHNhdmVkIHRoZW0gYW5kIHJlLWxvYWRlZCB0aGVtIHRvIHNhdmUgdGltZS4gSSBoYXZlIGFsc28gc2F2ZWQgdGhlIHN1bW1hcnkgZGF0YSBwcm9kdWNlZCBmcm9tIHRoZSBtb2RlbHMsIHRvIHNhdmUgdGltZSwgeW91IGNhbiBzaW1wbHkgc2tpcCB0aGUgaGFzaGVkIGNvZGUgYW5kIGlucHV0IHRoZSByZXN1bHRpbmcgc3VtbWFyeSBkYXRhLg0KDQpXZSB3aWxsIHJ1biBvdXIgY3VzdG9tIGZ1bmN0aW9uLCBgYmF5ZXNfaW5jcmVtZW50YWxfcmVncmVzc2lvbl9ieV9pZGAuDQoNCkxldCdzIG1ha2UgZGVmaW5lIHRoZSBvdXRwdXQgZGlyZWN0b3J5DQoNCmBgYHtyfQ0Kb3V0cHV0X21vZHNfYmF5ZXNfd2QgPC0gcGFzdGUwKHdkLCAiLi9vdXRwdXQtbW9kLi9iYXllcy1yZWdzIikNCmBgYA0KDQrij63vuI8gKipTa2lwIHRoaXMgc3RlcCoqIGlmIHlvdSBoYXZlIGFscmVhZHkgcnVuIHRoaXMgb25jZSwgb3IgaGF2ZSBkb3dubG9hZGVkIHRoZSBzYXZlZCBtb2RlbHMgb3Igc2F2ZWQgZGF0YSBmaWxlcyBmcm9tIEdpdEh1YiAodGhhdCdzIHdoeSBpdHMgaGFzaGVkIG91dCkuIOKMmypUaGlzIGNvZGUgdGFrZXMgYSB3aGlsZSB0byBydW4gKuKMmw0KDQpEdXJpbmcgdGhpcyBwYXJ0IG9mIHRoZSBzY3JpcHQgSSByZWNlaXZlZCBhbiBlcnJvciwgJ0NhdXNlZCBieSBlcnJvciBpbiBgc29ja2V0Q29ubmVjdGlvbigpYDonLiBJIHRoaW5rIHRoZSBzeXN0ZW0gbWF5IGJlIGhpdHRpbmcgYSBsaW1pdCBvbiB0aGUgbnVtYmVyIG9mIHNpbXVsdGFuZW91cyBzb2NrZXQgY29ubmVjdGlvbnMuIElmIHlvdSB0aGlzIHBhcnQgb2YgdGhlIGNvZGUgYW5kIGFsc28gZ2V0IHRoaXMgaXNzdWUsIHRyeSByZWR1Y2luZyB0aGUgbnVtYmVyIG9mIHBhcmFsbGVsIHdvcmtlcnM6IHBsYW4obXVsdGlzZXNzaW9uLCB3b3JrZXJzID0gMiksIG9yIHJ1biBhZ2FpbiBhZnRlciB0aGUgZXJyb3IuDQoNCmBgYHtyLCByZXN1bHRzPSdoaWRlJ30NCiMgaWRzIDwtIHNsb3BlX3RpZHkgJT4lDQojICAgZHBseXI6OmRpc3RpbmN0KGlkKSAlPiUNCiMgICBwdWxsKGlkKQ0KIyANCiMgcGxhbihtdWx0aXNlc3Npb24pDQojIA0KIyBmdXR1cmVfbWFwKA0KIyAgIGlkcywNCiMgICBiYXllc19pbmNyZW1lbnRhbF9yZWdyZXNzaW9uX2J5X2lkLA0KIyAgIGlkX25hbWUgPSAiaWQiLA0KIyAgIGRhdGEgPSBzbG9wZV90aWR5LA0KIyAgIHJlc3BvbnNlID0gIk1PMl9nIiwNCiMgICBwcmVkaWN0b3IgPSAiRE8iLA0KIyAgIHNlZWRfbnVtYmVyID0gMTQzMDE5LA0KIyAgIHNhdmVfbW9kZWxzID0gVFJVRSwNCiMgICBtb2Rfb3V0cHV0X3dkID0gb3V0cHV0X21vZHNfYmF5ZXNfd2QNCiMgKQ0KIyANCiMgcGxhbihzZXF1ZW50aWFsKQ0KYGBgDQoNCkxvYWQgYWxsIG1vZGVscyBhbmQgc3RvcmUgaW4gYSBsaXN0LCB3aWxsIHVzZSBhIGxvdCBvZiBtZW1vcnkuIFlvdSBjYW4gYWxzbyBza2lwIHRoaXMgc3RlcCBhbmQgbG9hZCB0aGUgcmVzdWx0aW5nIGRhdGEgZnJhbWVzIGJlbG93LiBJIGFtIHVzaW5nIHRoZSBjdXN0b20gZnVuY3Rpb24gYGxvYWRfcmRzYCwgc28gd2UgY2FuIGNvbXBhcmUgdGhlbSBhbmQgZ2VuZXJhdGUgcHJlZGljdGlvbnMuDQoNCuKPre+4jyAqKlNraXAgdGhpcyBzdGVwKiogaWYgeW91IGhhdmUgZG93bmxvYWRlZCB0aGUgc2F2ZWQgZGF0YSBwdWxsZWQgZnJvbSB0aGVzZSBtb2RlbHMgaGF2ZSBhbHNvIGhhc2VkIHRoaXMgb3V0LCBiYXllc19yZWdfbW9kc19maXQuY3N2JyBhbmQgJ2JheWVzX3JlZ19tb2RzX3ByZWRpY3Rpb25zLmNzdicuIFRoZXNlIGFyZSBpbiB0aGUgbW9kLWRhdGEgZGlyZWN0b3J5Lg0KDQpgYGB7cn0NCiMgYmF5ZXNfcmVnX21vZHMgPC0gbG9hZF9yZHMobW9kZWxfZHcgPSBvdXRwdXRfbW9kc19iYXllc193ZCkNCmBgYA0KDQojIyMgTW9kZWwgZml0cw0KDQrij63vuI8gKipTa2lwIHRoaXMgc3RlcCoqIGlmIHlvdSBoYXZlIGRvd25sb2FkZWQgKirwn5K/IGJheWVzX3JlZ19tb2RzX2ZpdC5jc3YqKi4NCg0KSXQgZ2V0cyBtb2RlbCBmaXQgcGFyYW1ldGVycyBsb28gYW5kIHIyIHVzaW5nIHRoZSBjdXN0b20gZnVuY3Rpb24sIGBpbmNyZW1lbnRhbF9yZWdyZXNzaW9uX2JheWVzX2ZpdHNgLiAq4oybIFRoaXMgY29kZSB0YWtlcyBhIHdoaWxlIHRvIHJ1biDijJsqDQoNCmBgYHtyfQ0KIyBiYXllc19yZWdfbW9kc19maXQgPC0gaW5jcmVtZW50YWxfcmVncmVzc2lvbl9iYXllc19maXRzKG1vZGVscyA9IGJheWVzX3JlZ19tb2RzKQ0KIyB3cml0ZS5jc3YoYmF5ZXNfcmVnX21vZHNfZml0LCBwYXN0ZTAobW9kX2RhdGFfd2QsICIuL2JheWVzX3JlZ19tb2RzX2ZpdC5jc3YiKSwgcm93Lm5hbWVzID0gRkFMU0UpDQpgYGANCg0KUmVhZGluZyBpbiB0aGlzIG1vZGVsIGZpdCBkYXRhIGZyYW1lLCBpbiB0aGUgY2FzZSB5b3UgZGlkIG5vdCBsb2FkIGluIGFsbCB0aGUgbW9kZWxzLg0KDQpgYGB7cn0NCmJheWVzX3JlZ19tb2RzX2ZpdCA8LSByZWFkLmNzdihwYXN0ZTAobW9kX2RhdGFfd2QsICIuL2JheWVzX3JlZ19tb2RzX2ZpdC5jc3YiKSkNCmBgYA0KDQoqKlNlbGVjdGluZyB0aGUgYmVzdCBmaXR0aW5nIG1vZGVsKioNCg0KZWxwZF9sb28sIG9yIHRoZSBleHBlY3RlZCBsb2cgcG9pbnR3aXNlIHByZWRpY3RpdmUgZGVuc2l0eSBmb3IgbGVhdmUtb25lLW91dCBjcm9zcy12YWxpZGF0aW9uLCBpcyBhIG1ldHJpYyB1c2VkIGluIEJheWVzaWFuIG1vZGVsIGV2YWx1YXRpb24gdG8gYXNzZXNzIHRoZSBwcmVkaWN0aXZlIGFjY3VyYWN5IG9mIGEgbW9kZWwuIFRoZSBlbHBkX2xvbyBpcyBhbiBhcHByb3hpbWF0aW9uIG9mIGhvdyB3ZWxsIHRoZSBtb2RlbCBpcyBleHBlY3RlZCB0byBwcmVkaWN0IG5ldyBkYXRhLCBiYXNlZCBvbiBsZWF2ZS1vbmUtb3V0IGNyb3NzLXZhbGlkYXRpb24uIEhpZ2hlciBlbHBkX2xvbyB2YWx1ZXMgaW5kaWNhdGUgYmV0dGVyIHByZWRpY3RpdmUgcGVyZm9ybWFuY2UuDQoNCmBgYHtyfQ0KYmVzdF9maXRfYmF5ZXNfcmVnIDwtIGJheWVzX3JlZ19tb2RzX2ZpdCAlPiUNCiAgZHBseXI6Omdyb3VwX2J5KGlkKSAlPiUNCiAgZHBseXI6Om11dGF0ZShlbHBkX2xvb19yYW5rID0gcmFuaygtZWxwZF9sb28pKSAlPiUNCiAgZHBseXI6OnNlbGVjdChpZCwgbW9kZWxfdHlwZSwgZWxwZF9sb28sIHIyLCBlbHBkX2xvb19yYW5rLCByMl9xMi41LCByMl9xOTcuNSwgZXN0aW1hdGVfRE8sIGNvbmYubG93X0RPLCBjb25mLmhpZ2hfRE8pICU+JQ0KICB1bmdyb3VwKCkNCmBgYA0KDQojIyMgTW9kZWwgcHJlZGljdGlvbnMNCg0K4o+t77iPICoqU2tpcCB0aGlzIHN0ZXAqKiBpZiB5b3UgaGF2ZSBkb3dubG9hZGVkICoq8J+SvyBiYXllc19yZWdfbW9kc19wcmVkaWN0aW9ucy5jc3YqKi4NCg0KSXQgcHVsbHMgb3VyIG1vZGVsIHByZWRpY3Rpb25zIHVzaW5nIGEgY3VzdG9tIGZ1bmN0aW9uIGBiYXllc19tb2RfcHJlZGljdGlvbnNgLg0KDQpgYGB7cn0NCiMgYmF5ZXNfcmVnX21vZHNfcHJlZGljdGlvbnMgPC0gYmF5ZXNfbW9kX3ByZWRpY3Rpb25zKG1vZGVscyA9IGJheWVzX3JlZ19tb2RzLCBvcmlnaW5hbF9kYXRhID0gc2xvcGVfdGlkeSkNCiMgd3JpdGUuY3N2KGJheWVzX3JlZ19tb2RzX3ByZWRpY3Rpb25zLCBwYXN0ZTAobW9kX2RhdGFfd2QsICIuL2JheWVzX3JlZ19tb2RzX3ByZWRpY3Rpb25zLmNzdiIpLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KDQpSZWFkaW5nIGluIHRoZSBwcmVkaWN0ZWQgZGF0YQ0KDQpgYGB7cn0NCmJheWVzX3JlZ19tb2RzX3ByZWRpY3Rpb25zIDwtIHJlYWQuY3N2KHBhc3RlMChtb2RfZGF0YV93ZCwgIi4vYmF5ZXNfcmVnX21vZHNfcHJlZGljdGlvbnMuY3N2IikpDQpgYGANCg0KV2UgYXJlIGdvaW5nIHRvIGNvbWJpbmVkIHRoaXMgd2l0aCBvdXIgYmVzdCBmaXR0aW5nIG1vZGVsIGRmLCBzbyB3ZSBrbm93IGhvdyB0aGV5IHJhbmtzIGZvciBMT08uDQoNCmBgYHtyfQ0KYmF5ZXNfcmVnX21vZHNfcHJlZGljdGlvbnMgPC0gbGVmdF9qb2luKGJheWVzX3JlZ19tb2RzX3ByZWRpY3Rpb25zLCBiZXN0X2ZpdF9iYXllc19yZWcsIGJ5ID0gYygiaWQiLCAibW9kZWxfdHlwZSIpKQ0KYGBgDQoNCiMjIyDwn5OIIFJlc3VsdHMNCg0KIyMjIyBNb2RlbCBzZWxlY3Rpb24gc3VtbWFyeQ0KDQpJbiBtb3N0IGNhc2VzLCB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gTU88c3ViPjI8L3N1Yj4gYW5kIERPIHdhcyBiZXN0IG1vZGVsbGVkIHdpdGggYSAyXm5kXi1vcmRlciBwb2x5bm9taWFsICgqbiogPSAyMiwgMzglIG9mIGZpc2gpLCBmb2xsb3dlZCBieSBhIDNecmReLW9yZGVyIHBvbHlub21pYWwgKCpuKiA9IDE1LCAyNiUpLCAxXnN0Xi1vcmRlciBwb2x5bm9taWFsICgqbiogPSAxMSwgMTklKSwgYW5kIGZpbmFsbHkgMF50aF4tb3JkZXIgcG9seW5vbWlhbCAoKm4qID0gMTAsIDE3JSkuDQoNCkZvciB0aGUgdHdvIG1vc3QgY29tbW9uIG1vZGVscywgMl5uZF4tIGFuZCAzXnJkXi1vcmRlciBwb2x5bm9taWFscywgdGhpcyBjb3VsZCBzdWdnZXN0IHRoZSBwcmVzZW5jZSBvZiBhIGNyaXRpY2FsIG94eWdlbiB0aHJlc2hvbGQgKFBjcml0KSB3aGVyZSB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gTU88c3ViPjI8L3N1Yj4gYW5kIE88c3ViPjI8L3N1Yj4gY2hhbmdlcy4gVG8gY29uZmlybSB0aGUgcHJlc2VuY2Ugb2YgYSBQY3JpdCwgd2UgbmVlZCB0byB2YWxpZGF0ZWQgdGhlIHNoYXBlIG9mIHRoZSBwb2x5bm9taWFscyAoc2VlIFBjcml0IG1vZGVsIGJlbG93KS4gSW4gYW55IGNhc2UsIHRoZXNlIHR5cGUgb2YgbW9kZWxzIGFyZSBpbmRpY2F0aXZlIG9mICoqb3h5cmVndWxhdG9yKiouDQoNClRoZSBuZXh0IG1vc3QgY29tbW9uIG1vZGVsIHdhcyBpcyAxXnN0Xi1vcmRlciBwb2x5bm9taWFsLiBJbiB0aGUgY2FzZSBvZiB0aGUgMV5zdF4tb3JkZXIgcG9seW5vbWlhbHMsIGl0IHN1Z2dlc3QgdGhlIHByZXNlbmNlcyBvZiBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gbzIgYW5kIE1PMiwgd2hpY2ggaXMgaW5kaWNhdGl2ZSBvZiAqKm94eWNvbmZvcm1lcioqLiBIb3dldmVyLCB0byBiZSB0cnVlIGV2aWRlbmNlIG9mIGEgb3h5Y29uZm9ybWVyIHRoaXMgcmVsYXRpb25zaGlwIHNob3VsZCBiZSBwb3NpdGl2ZSAoaS5lLiBhcyBPPHN1Yj4yPC9zdWI+IGZhbGxzIE1PPHN1Yj4yPC9zdWI+IGFsc28gZmFsbHMpLiAxMyBvZiB0aGUgMTggaW5kaXZpZHVhbHMgYmVzdCBtb2RlbGxlZCB3aXRoIGEgbGluZWFyIGZ1bmN0aW9uIGhhZCBwb3NpdGl2ZSBlc3RpbWF0ZXMgd2l0aCBjcmVkaWJsZSBpbnRlcnZhbHMgdGhhdCBkaWQgbm90IG92ZXJsYXAgd2l0aCB6ZXJvIChUYWJsZSBTMykuDQoNCkxhc3RseSwgMF50aF4tb3JkZXIgd2FzIHRoZSBsZWFzdCBjb21tb24gKCpuKiA9IDMsIDUlKSwgaXQgc3VnZ2VzdHMgdGhhdCBNTzxzdWI+Mjwvc3ViPiBkb2VzIG5vdCBzaG93IGEgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBkZXBlbmRlbmNlIG9uIHRoZSBPPHN1Yj4yPC9zdWI+LiBJbiBvdGhlciB3b3JkcywgdGhlIG1ldGFib2xpYyByYXRlIGRvZXMgbm90IGFkanVzdCBiYXNlZCBvbiBveHlnZW4gYXZhaWxhYmlsaXR5LCBhbmQgdGhlcmUgaXMgbm8gY2xlYXIgY3JpdGljYWwgb3h5Z2VuIHRocmVzaG9sZCAoUGNyaXQpIHdoZXJlIHRoZSByZWxhdGlvbnNoaXAgY2hhbmdlcy4gVGhpcyBpcyBpbmRpY2F0aXZlIG9mIGEgKipveHlyZWd1bGF0b3IqKi4NCg0KYGBge3J9DQpiZXN0X21vZCA8LSBiZXN0X2ZpdF9iYXllc19yZWcgJT4lIA0KICBkcGx5cjo6ZmlsdGVyKGVscGRfbG9vX3JhbmsgPT0gMSkNCg0KdG90YWxfZmlzaCA8LSBucm93KGJlc3RfbW9kKQ0KDQptb2Rfc3VtbWFyeV90YWJsZSA8LSBiZXN0X21vZCAlPiUgDQogIGRwbHlyOjpncm91cF9ieShtb2RlbF90eXBlKSAlPiUgDQogIGRwbHlyOjpyZWZyYW1lKG4gPSBsZW5ndGgoaWQpLA0KICAgICAgICAgICAgICAgICBwZXJjZW50ID0gcm91bmQoKG4vdG90YWxfZmlzaCkqMTAwLDIpKSAlPiUgDQogIGRwbHlyOjptdXRhdGUoYmVzdF9tb2RlbF9uYW1lID0gY2FzZV93aGVuKA0KICAgICAgbW9kZWxfdHlwZSA9PSAibG1fMCIgfiAiMHRoLW9yZGVyIHBvbHlub21pYWwiLA0KICAgICAgbW9kZWxfdHlwZSA9PSAibG1fMSIgfiAiMXN0LW9yZGVyIHBvbHlub21pYWwiLA0KICAgICAgbW9kZWxfdHlwZSA9PSAibG1fMiIgfiAiMm5kLW9yZGVyIHBvbHlub21pYWwiLA0KICAgICAgbW9kZWxfdHlwZSA9PSAibG1fMyIgfiAiM3JkLW9yZGVyIHBvbHlub21pYWwiLA0KICAgICAgVFJVRSB+ICJFUlJPUiINCiAgICApKQ0KDQoNCnRhYmxlX2J3bSA8LSBtb2Rfc3VtbWFyeV90YWJsZSAlPiUgDQogIGRwbHlyOjpzZWxlY3QoYmVzdF9tb2RlbF9uYW1lLCBldmVyeXRoaW5nKCksIC1tb2RlbF90eXBlKSAlPiUgDQogICBndCgpICU+JSANCiAgY29sc19hbGlnbigNCiAgICBhbGlnbiA9ICJjZW50ZXIiLCANCiAgICBjb2x1bW5zID0gZXZlcnl0aGluZygpDQogICkNCg0KdGFibGVfYndtDQpgYGANCg0KU3VtbWFyeSBvZiBmaXNoIGJlc3QgbW9kZWwgd2l0aCBhIGxpbmVhciBmdW5jdGlvbi4NCg0KIyMjIFRhYmxlIFMzDQoNCioqVGFibGUgUzM6KiogVGVuIGZpc2ggdGhhdCB3ZXJlIGJlc3QgbW9kZWxsZWQgd2l0aCBhIGxpbmVhciBmdW5jdGlvbiwgc2hvd2luZyByXjJeLCBhbmQgZXN0aW1hdGUgKCkuIE9ubHkgdHdvIGZpc2ggaGFkIHBvc2l0aXZlIGVzdGltYXRlcyB3aXRoIGNyZWRpYmxlIGludGVydmFscyB0aGF0IGRpZCBub3Qgb3ZlcmxhcCB3aXRoIHplcm8sIHdoaWNoIGFyZSBoaWdobGlnaHRlZCBhcyBjb25mb3JtaW5nIGluIHRoZSB0YWJsZS4gVGh1cyBpbiB0b3RhbCwgMTMgb2YgNTggZmlzaCBzaG93ZWQgc3VmZmljaWVudCBldmlkZW5jZSB0byBiZSBjb25mb3JtaW5nLg0KDQpgYGB7cn0NCnRhYmxlX2xtXzEgPC0gYmVzdF9tb2QgJT4lIA0KICBkcGx5cjo6ZmlsdGVyKG1vZGVsX3R5cGUgPT0gImxtXzEiKSAlPiUgDQogIGRwbHlyOjptdXRhdGUocl9zcV9jaSA9IHBhc3RlMChmb3JtYXQocm91bmQocjIsIDMpLCBzY2llbnRpZmljID0gRkFMU0UpLCAiICgiLCANCiAgICAgICAgICAgICAgICAgICBmb3JtYXQocm91bmQocjJfcTIuNSwgMyksIHNjaWVudGlmaWMgPSBGQUxTRSksICIgdG8gIiwgDQogICAgICAgICAgICAgICAgICAgZm9ybWF0KHJvdW5kKHIyX3E5Ny41LCAzKSwgc2NpZW50aWZpYyA9IEZBTFNFKSwgIikiKSwNCiAgZXN0X2NpID0gcGFzdGUwKGZvcm1hdChyb3VuZChlc3RpbWF0ZV9ETywgNCksIHNjaWVudGlmaWMgPSBGQUxTRSksICIgKCIsIA0KICAgICAgICAgICAgICAgICAgZm9ybWF0KHJvdW5kKGNvbmYubG93X0RPLCA0KSwgc2NpZW50aWZpYyA9IEZBTFNFKSwgIiB0byAiLCANCiAgICAgICAgICAgICAgICAgIGZvcm1hdChyb3VuZChjb25mLmhpZ2hfRE8sIDQpLCBzY2llbnRpZmljID0gRkFMU0UpLCAiKSIpLA0KICAgICAgICAgICAgICAgIGNvbmZvcm1lciA9IGlmX2Vsc2UoY29uZi5sb3dfRE8gPiAwLCAiQ29uZm9ybWluZyIsICJOb3QgY29uZm9ybWluZyIpKSAlPiUgDQogIGRwbHlyOjpzZWxlY3QoaWQsIGVzdGltYXRlX0RPLCByX3NxX2NpLCBlc3RfY2ksIGNvbmZvcm1lcikgJT4lIA0KICBkcGx5cjo6YXJyYW5nZShjb25mb3JtZXIsIGRlc2MoZXN0X2NpKSkgJT4lIA0KICBkcGx5cjo6dW5ncm91cCgpDQoNCmZpcnN0X29yZGVyX2lkcyA8LSB0YWJsZV9sbV8xICU+JSANCiAgZGlzdGluY3QoaWQpICU+JSANCiAgcHVsbCguKQ0KDQptZWFuX21vMiA8LSBzbG9wZV90aWR5ICU+JSANCiAgZHBseXI6OmZpbHRlcihpZCAlaW4lIGZpcnN0X29yZGVyX2lkcykgJT4lIA0KICBkcGx5cjo6Z3JvdXBfYnkoaWQpICU+JSANCiAgZHBseXI6OnJlZnJhbWUobWVhbl9NTzJfZyA9IG1lYW4oTU8yX2csIG5hLnJtID0gVFJVRSkpDQoNCnRhYmxlX2xtXzEgPC0gbGVmdF9qb2luKHRhYmxlX2xtXzEsIG1lYW5fbW8yLCBieSA9ICJpZCIpIA0KDQp0YWJsZV9sbV8xIDwtICB0YWJsZV9sbV8xICU+JSANCiAgZHBseXI6Om11dGF0ZShwZXJjZW50X2NoYW5nZSA9IChlc3RpbWF0ZV9ETy9tZWFuX01PMl9nKSoxMDApICU+JSANCiAgZHBseXI6OnNlbGVjdChpZCwgcl9zcV9jaSwgZXN0X2NpLCBwZXJjZW50X2NoYW5nZSwgY29uZm9ybWVyKQ0KDQoNCnRhYmxlX2xtXzEgJT4lIA0KICBndCgpICU+JSANCiAgY29sc19hbGlnbigNCiAgICBhbGlnbiA9ICJjZW50ZXIiLCANCiAgICBjb2x1bW5zID0gZXZlcnl0aGluZygpDQogICkgJT4lIA0KICBjb2xzX2xhYmVsKA0KICAgIGlkID0gIkZpc2ggSUQiLA0KICAgIHJfc3FfY2kgPSAicjIgKENJKSIsDQogICAgZXN0X2NpID0gIkVzdGltYXRlIChDSSkiLA0KICAgIHBlcmNlbnRfY2hhbmdlID0gIlBlcmNlbnRhZ2UgY2hhbmdlIiwNCiAgICBjb25mb3JtZXIgPSAiRXZpZGVuY2Ugb2Ygb3h5Y29uZm9ybWluZyINCiAgKQ0KYGBgDQoNCiMjIyMgUGxvdGluZyBhbGwgbW9kZWxzDQoNCkRhdGEgc2V0IHdpdGggYWxsIHNsb3BlcyBhbmQgd2hpY2ggbW9kZWwgd2FzIGJlc3QNCg0KYGBge3J9DQpiZXN0X2ZpdCA8LSBsZWZ0X2pvaW4oc2xvcGVfdGlkeSwgYmVzdF9tb2QsIGJ5ID0gImlkIikNCmBgYA0KDQpTYXZpbmcgYWxsIHJlZ3Jlc3Npb24sIGFuZCBoaWdobGlnaHRpbmcgdGhlIG1vZGVsIHRoYXQgaGFzIHRoZSBiZXN0IGZpdCwgYmFzZWQgb24gQUlDIHZhbHVlcy4gVGhpcyBpcyBjYWxsZWQgYGNvbWJpbmVkX3JlZ19wbG90cy5wZGZgDQoNCmBgYHtyLCBmaWcuaGVpZ2h0ID0gMywgZmlnLndpZHRoPSA0fQ0KIyAjIENyZWF0ZSBhIGxpc3QgdG8gc3RvcmUgdGhlIHBsb3RzDQojIHBsb3RzIDwtIGxpc3QoKQ0KIyBtb2RlbF9wcmVkc19saXN0IDwtIGxpc3QoKQ0KIyBpbmNyZW1lbnRhbF9yZWdfYmF5ZXNfd2QgPC0gcGFzdGUwKG91dHB1dF9maWdfd2QsICIuL2luY3JlbWVudGFsX3JlZ3Jlc3Npb25zIikNCiMgDQojIGZvciAoaWRfaSBpbiBpZHMpIHsNCiMgICANCiMgICAjIEZpbHRlciBkYXRhIGZvciB0aGUgY3VycmVudCBJRA0KIyAgIGRmX2kgPC0gYmF5ZXNfcmVnX21vZHNfcHJlZGljdGlvbnMgJT4lDQojICAgICBkcGx5cjo6ZmlsdGVyKGlkID09IGlkX2kpICU+JSANCiMgICAgIGRwbHlyOjptdXRhdGUobGluZV9zaXplID0gaWZfZWxzZShlbHBkX2xvb19yYW5rID09IDEsIDIsIDEpLA0KIyAgICAgICAgICAgIGFscGhhX3ZhbHVlID0gaWZfZWxzZShlbHBkX2xvb19yYW5rID09IDEsIDEsIDAuNCkpDQojICAgDQojICAgeF9taW4gPC0gZGZfaSAlPiUNCiMgICAgIGRwbHlyOjpyZWZyYW1lKG1pbiA9IG1pbihETyksIG5hLnJtID0gVFJVRSkgJT4lIA0KIyAgICAgZHBseXI6OnB1bGwobWluKQ0KIyAgIA0KIyAgIHlfbWF4IDwtIGRmX2kgJT4lDQojICAgICBkcGx5cjo6cmVmcmFtZShtYXggPSBtYXgoTU8yX2cpLCBuYS5ybSA9IFRSVUUpICU+JSANCiMgICAgIGRwbHlyOjpwdWxsKG1heCkNCiMgICANCiMgICBiZXN0X3dlaWdodGVkX21vZGVsX2kgPC0gYmVzdF9maXRfYmF5ZXNfcmVnICU+JSANCiMgICAgIGRwbHlyOjpmaWx0ZXIoaWQgPT0gaWRfaSAmIGVscGRfbG9vX3JhbmsgPT0gMSkNCiMgICANCiMgICBwb2x5X2lfbmFtZSA8LSBiZXN0X3dlaWdodGVkX21vZGVsX2kgJT4lDQojICAgICBkcGx5cjo6bXV0YXRlKG5hbWUgPSBjYXNlX3doZW4oDQojICAgICAgIG1vZGVsX3R5cGUgPT0gImxtXzAiIH4gIjB0aC1vcmRlciIsDQojICAgICAgIG1vZGVsX3R5cGUgPT0gImxtXzEiIH4gIjFzdC1vcmRlciIsDQojICAgICAgIG1vZGVsX3R5cGUgPT0gImxtXzIiIH4gIjJuZC1vcmRlciIsDQojICAgICAgIG1vZGVsX3R5cGUgPT0gImxtXzMiIH4gIjNyZC1vcmRlciIsDQojICAgICAgIFRSVUUgfiAiRVJST1IiDQojICAgICApKSAlPiUgDQojICAgICBkcGx5cjo6cHVsbChuYW1lKQ0KIyAgIA0KIyAgIHJfaSA8LSBiZXN0X3dlaWdodGVkX21vZGVsX2kgJT4lIA0KIyAgICAgZHBseXI6Om11dGF0ZShyX3NxX2NpID0gcGFzdGUwKHJvdW5kKHIyLCAzKSwgIiAoIiwgDQojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKHIyX3EyLjUsIDMpLCAi4oCTIiwgDQojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKHIyX3E5Ny41LCAzKSwgIikiKSkgJT4lIA0KIyAgICAgZHBseXI6OnB1bGwocl9zcV9jaSkNCiMgDQojICAgIyBDcmVhdGUgdGhlIHBsb3QNCiMgICBwbG90X2kgPC0gZ2dwbG90KCkgKw0KIyAgICAgZ2VvbV9yaWJib24oZGF0YSA9IGRmX2ksDQojICAgICAgICAgICAgICAgICBhZXMoeCA9IERPLCB5ID0gcHJlZGljdGVkLCB5bWluID0gcHJlZF9sb3dlciwgeW1heCA9IHByZWRfdXBwZXIsIGZpbGwgPSBtb2RlbF90eXBlKSwNCiMgICAgICAgICAgICAgICAgIGFscGhhID0gMC4xKSArDQojICAgICBnZW9tX2xpbmUoZGF0YSA9IGRmX2ksIA0KIyAgICAgICAgICAgICAgIGFlcyh4ID0gRE8sIHkgPSBwcmVkaWN0ZWQsIGNvbG91ciA9IG1vZGVsX3R5cGUsIGxpbmV3aWR0aCA9IGxpbmVfc2l6ZSwgYWxwaGEgPSBhbHBoYV92YWx1ZSkpICsNCiMgICAgIGdlb21fcG9pbnQoZGF0YSA9IGRmX2kgJT4lIGRwbHlyOjpmaWx0ZXIoZWxwZF9sb29fcmFuayA9PSAxKSwgYWVzKHggPSBETywgeSA9IE1PMl9nKSwgYWxwaGEgPSAwLjYsIGNvbG91ciA9ICJibGFjayIsIHNpemUgPSAyKSArDQojICAgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoInJlZCIsICJibHVlIiwgImdyZWVuIiwgInB1cnBsZSIpLCANCiMgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiMHRoIE9yZGVyIiwgIjFzdCBPcmRlciIsICIybmQgT3JkZXIiLCAiM3JkIE9yZGVyIikpICsNCiMgICAgIHNjYWxlX3NpemVfaWRlbnRpdHkoKSArICAjIFVzZSB0aGUgc2l6ZSB2YWx1ZXMgZGlyZWN0bHkNCiMgICAgIHNjYWxlX2FscGhhX2lkZW50aXR5KGd1aWRlID0gIm5vbmUiKSArICAjIFJlbW92ZSB0aGUgYWxwaGEgbGVnZW5kIA0KIyAgICAgYW5ub3RhdGUoInRleHQiLCB4ID0geF9taW4sIA0KIyAgICAgICAgICAgICAgeSA9IHlfbWF4LCANCiMgICAgICAgICAgICAgIGxhYmVsID0gcGFzdGUwKCJCZXN0IGZpdDogIixwb2x5X2lfbmFtZSwgIlxuIiwgInIyID0gIiwgcl9pKSwgDQojICAgICAgICAgICAgICBoanVzdCA9IDAsIHZqdXN0ID0gMSwgc2l6ZSA9IDQpICsNCiMgICAgIGxhYnMoDQojICAgICAgIHRpdGxlID0gcGFzdGUoaWRfaSksDQojICAgICAgIHggPSAiRGlzc29sdmVkIG94eWdlbiBwZXJjZW50YWdlIChETykiLA0KIyAgICAgICB5ID0gIk1PMiAobzIgbWcvZy9oKSIsDQojICAgICAgIGNvbG91ciA9ICJNb2RlbCIpICsNCiMgICAgIHRoZW1lX2NsYXNzaWMoKSArDQojICAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQojICAgDQojICAgIyBTdG9yZSB0aGUgcGxvdA0KIyAgIHBsb3RzW1tpZF9pXV0gPC0gcGxvdF9pDQojICAgDQojICAgcHJpbnQocGxvdF9pKQ0KIyB9DQojIA0KIyANCiMgcGRmKGZpbGUgPSBwYXN0ZTAoaW5jcmVtZW50YWxfcmVnX2JheWVzX3dkLCAiLi9jb21iaW5lZF9yZWdfcGxvdHMucGRmIiksIHdpZHRoID0gOCwgaGVpZ2h0ID0gNikNCiMgDQojIGRldi5vZmYoKSAgIyBDbG9zZSB0aGUgUERGIGRldmljZQ0KYGBgDQoNCkdldHRpbmcgYSBwbG90IGZvciBlYWNoIGJlc3QgZml0IHJlZ3Jlc3Npb24sIGFuZCBvdmVybGF5aW5nIGEgZ2xvYmFsIG1vZGVsIGZvciB0aGF0IG1vZGVsIHR5cGUuDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0Kb3V0cHV0X21vZHNfYmF5ZXNfZ2xvYmFsX3dkIDwtIHBhc3RlMChvdXRwdXRfbW9kc193ZCwgIi4vYmF5ZXMtcmVncy1nbG9iYWwiKQ0KYGBgDQoNCkhlcmUgd2UgYXJlIGdyb3VwaW5nIGZpc2ggYnkgYmVzdCBmaXR0aW5nIG1vZGVsIGFuZCBnZXR0aW5nIGFuIGF2ZXJhZ2UgdHJlbmQuIEkgaGF2ZSBoYXNoZWQgdGhlIGNvZGUgc28geW91IGRvbid0IG5lZWQgdG8gcmUtcnVuIHRoZSBtb2RlbHMNCg0K4o+t77iPICoqU2tpcCB0aGlzIHN0ZXAqKiBpZiB5b3UgaGF2ZSBkb3dubG9hZGVkIHRoZSBnbG9iYWwgbW9kZWxzICoqJy5yZHMnKiogaW4gdGhlICdiYXllcy1yZWdzLWdsb2JhbCcgZm9sZGVyDQoNCmBgYHtyfQ0KIyBzZWVkX251bWJlciA9IDE0MzAxOQ0KIyANCiMgIyBTZXQgdXAgcGFyYWxsZWwgYmFja2VuZA0KIyBmdXR1cmU6OnBsYW4obXVsdGlzZXNzaW9uLCB3b3JrZXJzID0gNCkgICMgQWRqdXN0IHdvcmtlcnMgYmFzZWQgb24gc3lzdGVtIHJlc291cmNlcw0KIyANCiMgIyBEZWZpbmUgbW9kZWwgZm9ybXVsYXMgYW5kIGRhdGENCiMgbW9kZWxfZm9ybXVsYXMgPC0gbGlzdCgNCiMgICBsbV8wID0gYmYoTU8yX2cgfiAxLCBmYW1pbHkgPSBnYXVzc2lhbigpKSwNCiMgICBsbV8xID0gYmYoTU8yX2cgfiBETywgZmFtaWx5ID0gZ2F1c3NpYW4oKSksDQojICAgbG1fMiA9IGJmKE1PMl9nIH4gcG9seShETywgMiksIGZhbWlseSA9IGdhdXNzaWFuKCkpLA0KIyAgIGxtXzMgPSBiZihNTzJfZyB+IHBvbHkoRE8sIDMpLCBmYW1pbHkgPSBnYXVzc2lhbigpKQ0KIyApDQojIA0KIyBtb2RlbF9kYXRhIDwtIGxpc3QoDQojICAgbG1fMCA9IGJlc3RfZml0ICU+JSBmaWx0ZXIobW9kZWxfdHlwZSA9PSAibG1fMCIpLA0KIyAgIGxtXzEgPSBiZXN0X2ZpdCAlPiUgZmlsdGVyKG1vZGVsX3R5cGUgPT0gImxtXzEiKSwNCiMgICBsbV8yID0gYmVzdF9maXQgJT4lIGZpbHRlcihtb2RlbF90eXBlID09ICJsbV8yIiksDQojICAgbG1fMyA9IGJlc3RfZml0ICU+JSBmaWx0ZXIobW9kZWxfdHlwZSA9PSAibG1fMyIpDQojICkNCiMgDQojICMgUnVuIG1vZGVscyBpbiBwYXJhbGxlbCB3aXRoIGZ1dHVyZV9tYXAoKQ0KIyBtb2RlbHMgPC0gZnV0dXJlX21hcChuYW1lcyhtb2RlbF9mb3JtdWxhcyksIH57DQojICAgYnJtKA0KIyAgICAgZm9ybXVsYSA9IG1vZGVsX2Zvcm11bGFzW1sueF1dLA0KIyAgICAgZGF0YSA9IG1vZGVsX2RhdGFbWy54XV0sDQojICAgICBjb3JlcyA9IDQsDQojICAgICBzZWVkID0gc2VlZF9udW1iZXIsDQojICAgICBzYXZlX3BhcnMgPSBzYXZlX3BhcnMoYWxsID0gVFJVRSksDQojICAgICBzYW1wbGVfcHJpb3IgPSBGQUxTRSwNCiMgICAgIHNpbGVudCA9IFRSVUUsDQojICAgICBmaWxlID0gcGFzdGUwKG91dHB1dF9tb2RzX2JheWVzX2dsb2JhbF93ZCwgIi4vIiwgLngsICJfZ2xvYmFsIikNCiMgICApDQojIH0pDQojIA0KIyAjIEFzc2lnbiBtb2RlbCBuYW1lcyB0byByZXN1bHRzDQojIG5hbWVzKG1vZGVscykgPC0gbmFtZXMobW9kZWxfZm9ybXVsYXMpDQojIA0KIyAjIFN0b3AgcGFyYWxsZWwgcGxhbiBhZnRlciBleGVjdXRpb24NCiMgZnV0dXJlOjpwbGFuKHNlcXVlbnRpYWwpDQpgYGANCg0K4o+t77iPICoqU2tpcCB0aGlzIHN0ZXAqKiBpZiB5b3UgaGF2ZSBkb3dubG9hZGVkIHRoZSBnbG9iYWxfbW9kZWxzX3ByZWRfZGYuY3N2DQoNCmBgYHtyfQ0KIyBnbG9iYWxfbW9kZWxzX3ByZWRzIDwtIGxpc3QoKQ0KIyANCiMgZm9yIChtb2RlX25hbWUgaW4gbmFtZXMoYmF5ZXNfcmVnX21vZHNfZ2xvYmFsKSkgew0KIyAgIA0KIyAgIG1vZF9pIDwtIGJheWVzX3JlZ19tb2RzX2dsb2JhbFtbbW9kZV9uYW1lXV0NCiMgICBtb2RlX3R5cGUgPSBzdHJfcmVtb3ZlKG1vZGVfbmFtZSwgIl9nbG9iYWwiKQ0KIyAgIA0KIyAgICBtb2RlbF9wcmVkaWN0aW9uc19pIDwtIGFzLmRhdGEuZnJhbWUoZml0dGVkKG1vZF9pLCBzdW1tYXJ5ID0gVFJVRSkpICU+JSANCiMgICAgICAgZHBseXI6Om11dGF0ZShtb2RlbCA9IG1vZGVfbmFtZSwNCiMgICAgICAgICAgICAgICAgICAgICBtb2RlbF90eXBlID0gbW9kZV90eXBlKSAlPiUgDQojICAgICAgIGRwbHlyOjpyZW5hbWUocHJlZF9sb3dlciA9IFEyLjUsIHByZWRfdXBwZXIgPSBROTcuNSwgcHJlZGljdGVkID0gRXN0aW1hdGUsIHByZWRfZXJyb3IgPSBFc3QuRXJyb3IpICU+JSANCiMgICAgICAgZHBseXI6OnNlbGVjdChtb2RlbCwgZXZlcnl0aGluZygpKQ0KIyAgICANCiMgICAgb3JpZ2luYWxfZGF0YV9pIDwtIGJlc3RfZml0ICU+JSBmaWx0ZXIobW9kZWxfdHlwZSA9PSBtb2RlX3R5cGUpICU+JSANCiMgICAgICBkcGx5cjo6c2VsZWN0KC1tb2RlbF90eXBlKQ0KIyAgICAgDQojICAgICBtb2RlbF9wcmVkaWN0aW9uc19vcmlnaW5hbF9pIDwtIGNiaW5kKG1vZGVsX3ByZWRpY3Rpb25zX2ksIG9yaWdpbmFsX2RhdGFfaSkNCiMgICAgIA0KIyAgICANCiMgICAgZ2xvYmFsX21vZGVsc19wcmVkc1tbbW9kZV9uYW1lXV0gPC0gbW9kZWxfcHJlZGljdGlvbnNfb3JpZ2luYWxfaQ0KIyB9DQojIA0KIyBnbG9iYWxfbW9kZWxzX3ByZWRfZGYgPC0gYmluZF9yb3dzKGdsb2JhbF9tb2RlbHNfcHJlZHMpDQojIA0KIyB3cml0ZS5jc3YoZ2xvYmFsX21vZGVsc19wcmVkX2RmLCAgcGFzdGUwKG1vZF9kYXRhX3dkLCAiLy5nbG9iYWxfbW9kZWxzX3ByZWRfZGYuY3N2IiksIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQoNCkxvYWQgZGF0YSBmcmFtZQ0KDQpgYGB7cn0NCmdsb2JhbF9tb2RlbHNfcHJlZF9kZiA8LSByZWFkLmNzdihwYXN0ZTAobW9kX2RhdGFfd2QsICIvLmdsb2JhbF9tb2RlbHNfcHJlZF9kZi5jc3YiKSkNCmBgYA0KDQojIyMjIEZpZ3VyZSBTNQ0KDQpCZXN0IGZpdCByZWdyZXNzaW9ucyB3aXRoIGdsb2JhbCBtb2RlbHMgYmFzZWQgb24gdGhhdCBwb2x5bm9taWFsIG9yZGVyLg0KDQpgYGB7cn0NCmdsb2JhbF9tb2RlbHNfcHJlZF9kZiA8LSBnbG9iYWxfbW9kZWxzX3ByZWRfZGYgJT4lDQogIGRwbHlyOjptdXRhdGUobW9kZWxfbmFtZSA9IGNhc2Vfd2hlbigNCiAgICAgIG1vZGVsX3R5cGUgPT0gImxtXzAiIH4gIjB0aC1vcmRlciBwb2x5bm9taWFsIiwNCiAgICAgIG1vZGVsX3R5cGUgPT0gImxtXzEiIH4gIjFzdC1vcmRlciBwb2x5bm9taWFsIiwNCiAgICAgIG1vZGVsX3R5cGUgPT0gImxtXzIiIH4gIjJuZC1vcmRlciBwb2x5bm9taWFsIiwNCiAgICAgIG1vZGVsX3R5cGUgPT0gImxtXzMiIH4gIjNyZC1vcmRlciBwb2x5bm9taWFsIiwNCiAgICAgIFRSVUUgfiAiRVJST1IiDQogICAgKSkNCg0KYW5ub3RhdGlvbl9kYXRhIDwtIG1vZF9zdW1tYXJ5X3RhYmxlICU+JQ0KICBkcGx5cjo6c2VsZWN0KG1vZGVsX3R5cGUsIGJlc3RfbW9kZWxfbmFtZSwgbikNCg0KYmF5ZXNfcmVnX21vZHNfcHJlZGljdGlvbnNfYmVzdCA8LSBiYXllc19yZWdfbW9kc19wcmVkaWN0aW9ucyAlPiUgDQogIGRwbHlyOjpmaWx0ZXIoZWxwZF9sb29fcmFuayA9PSAxKSANCg0KZmlnX3M1IDwtIGdncGxvdCgpICsNCiAgZ2VvbV9saW5lKGRhdGEgPSBiYXllc19yZWdfbW9kc19wcmVkaWN0aW9uc19iZXN0LA0KICAgICAgICAgICAgYWVzKHggPSBETywgeSA9IHByZWRpY3RlZCwgY29sb3IgPSBpZCksIHNpemUgPSAxKSArDQogICMgZ2VvbV9zbW9vdGgoZGF0YSA9IGJlc3RfZml0LA0KICAjICAgICAgICAgICBhZXMoeCA9IERPLCB5ID0gTU8yX2csIGNvbG9yID0gaWQpLCBzaXplID0gMSwgYWxwaGEgPSAxLCBzZSA9IEZBTFNFKSArDQogIGdlb21fcmliYm9uKGRhdGEgPSBnbG9iYWxfbW9kZWxzX3ByZWRfZGYsDQogICAgICAgICAgICAgIGFlcyh4ID0gRE8sIHltaW4gPSBwcmVkX2xvd2VyDQosIHltYXggPSBwcmVkX3VwcGVyLCBncm91cCA9IG1vZGVsKSwNCiAgICAgICAgICAgICAgZmlsbCA9ICIjRkM2Qzg1IiwgYWxwaGEgPSAwLjIpICsgICMgU2hhZGVkIGNvbmZpZGVuY2UgaW50ZXJ2YWxzDQogIGdlb21fbGluZShkYXRhID0gZ2xvYmFsX21vZGVsc19wcmVkX2RmLA0KICAgICAgICAgICAgYWVzKHggPSBETywgeSA9IHByZWRpY3RlZCksIGxpbmV3aWR0aCA9IDEuNSwgY29sb3IgPSAiI0ZGMDA3RiIpICsNCiAgZmFjZXRfd3JhcCh+bW9kZWxfdHlwZSkgKw0KICBzY2FsZV9jb2xvcl9ncmV5KHN0YXJ0ID0gMC4xLCBlbmQgPSAwLjkpICsNCiAgbGFicygNCiAgICAgIHRpdGxlID0gcGFzdGUoIkJlc3QgZml0IHJlZ3Jlc3Npb25zIGdyb3VwZWQgYnkgcG9seW5vbWlhbCBvcmRlciIpLA0KICAgICAgeCA9ICJEaXNzb2x2ZWQgb3h5Z2VuIHBlcmNlbnRhZ2UgKERPKSIsDQogICAgICB5ID0gIk1PMiAoTzIgbWcvZy9oKSIpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogIGdlb21fdGV4dChkYXRhID0gYW5ub3RhdGlvbl9kYXRhLA0KICAgICAgICAgICAgYWVzKHggPSAtSW5mLCB5ID0gSW5mLCBsYWJlbCA9IHBhc3RlMCgiaXRhbGljKG4pID09ICIsIG4pKSwNCiAgICAgICAgICAgIGhqdXN0ID0gLTAuMSwgdmp1c3QgPSAxLjIsIGluaGVyaXQuYWVzID0gRkFMU0UsIHBhcnNlID0gVFJVRSkNCmZpZ19zNQ0KYGBgDQoNCioqRmlndXJlIFM1OioqIEluZGl2aWR1YWwgcmVncmVzc2lvbiBjdXJ2ZXMgc2hvd2luZyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gbWFzcy1zcGVjaWZpYyBveHlnZW4gY29uc3VtcHRpb24gcmF0ZSAo4bmAT+KCgjsgbWfigbvCuSBP4oKCIGjigbvCuSkgYW5kIGFtYmllbnQgZGlzc29sdmVkIG94eWdlbiAoRE87ICUgc2F0dXJhdGlvbiksIGdyb3VwZWQgYnkgdGhlIGJlc3QtZml0dGluZyBwb2x5bm9taWFsIG9yZGVyICgw4bWXyrAgdG8gM8qz4bWIKS4gRWFjaCBwYW5lbCByZXByZXNlbnRzIGZpc2ggd2hvc2Ug4bmAT+KCguKAk0RPIHJlbGF0aW9uc2hpcCB3YXMgYmVzdCBtb2RlbGxlZCBieSB0aGF0IHBvbHlub21pYWwgb3JkZXIsIGJhc2VkIG9uIGxlYXZlLW9uZS1vdXQgY3Jvc3MtdmFsaWRhdGlvbiAoTE9PLUNWKS4gR3JleSBsaW5lcyByZXByZXNlbnQgaW5kaXZpZHVhbCBtb2RlbCBmaXRzOyB0aGUgYm9sZCBwaW5rIGxpbmUgc2hvd3MgdGhlIGdyb3VwLWxldmVsIHRyZW5kIHdpdGhpbiBlYWNoIHBvbHlub21pYWwgY2xhc3MuIEZpc2ggd2VyZSBtb3N0IGNvbW1vbmx5IGJlc3QgZml0IGJ5IGEgMuKBv+G1iC1vcmRlciBwb2x5bm9taWFsIChuID0gMjIpLCBmb2xsb3dlZCBieSAzyrPhtYgtb3JkZXIgKCpuKiA9IDE1KSwgMcui4bWXLW9yZGVyICgqbiogPSAxMSksIGFuZCAw4bWXyrAtb3JkZXIgKCoqbiA9IDEwKS4gSGlnaGVyLW9yZGVyIGZpdHMgKDLigb/htYggYW5kIDPKs+G1iCkgYW5kIDDhtZfKsC1vcmRlciBmaXRzIGFyZSBnZW5lcmFsbHkgaW5kaWNhdGl2ZSBvZiBveHlyZWd1bGF0aW5nIHJlc3BvbnNlcywgd2hpbGUgMcui4bWXLW9yZGVyIGZpdHMgbWF5IHN1Z2dlc3Qgb3h5Y29uZm9ybWluZyBiZWhhdmlvdXIgd2hlbiBwb3NpdGl2ZWx5IHNsb3BlZC4gIA0KDQoNCmBgYHtyfQ0KIyBnZ3NhdmUoZmlsZW5hbWUgPSBwYXN0ZTAob3V0cHV0X2ZpZ193ZCwgIi4vbXNfZmlndXJlcy4vZmlndXJlLTIucGRmIiksIA0KIyAgICAgICAgcGxvdCA9IGZpZ18yLA0KIyAgICAgICAgd2lkdGggPSAyMTAsDQojICAgICAgICBoZWlnaHQgPSAyOTcvMiwgICMgU3BlY2lmeSB0aGUgaGVpZ2h0IG9mIHRoZSBwbG90DQojICAgICAgICB1bml0cyA9ICJtbSIpDQpgYGANCg0KIyMgT+KCgmNyaXQgbW9kZWwNCg0KV2Ugd2lsbCBjYWxjdWxhdGUgT+KCgmNyaXQgdXNpbmcgQ2hhYm90IG1ldGhvZCBhbmQgZnVuY3Rpb24gYGNhbGNPMmNyaXRgLiAgDQoNClRoaXMgZnVuY3Rpb24gdXNlcyB0aGUgZmlmdGggcGVyY2VudGlsZSBvZiB0aGUgTU88c3ViPjI8L3N1Yj4gdmFsdWVzIG9ic2VydmVkIGF0IGRpc3NvbHZlZCBveHlnZW4gbGV2ZWxzIOKJpSA4MCUgYWlyIHNhdHVyYXRpb24gYXMgdGhlIGNyaXRlcmlvbiB0byBhc3Nlc3MgbG93IE1PPHN1Yj4yPC9zdWI+IHZhbHVlcy4gVGhlIGFsZ29yaXRobSB0aGVuIGlkZW50aWZpZXMgYWxsIHRoZSBNTzxzdWI+Mjwvc3ViPiBtZWFzdXJlbWVudHMgZ3JlYXRlciB0aGFuIHRoaXMgbWluaW1hbGx5IGFjY2VwdGFibGUgTU88c3ViPjI8L3N1Yj4gdmFsdWUuIFdpdGhpbiB0aGlzIHN1Yi1zZXQsIGl0IGlkZW50aWZpZXMgdGhlIE1PPHN1Yj4yPC9zdWI+MiBtZWFzdXJlbWVudCBtYWRlIGF0IHRoZSBsb3dlc3QgRE8gYW5kIHRoZXJlYWZ0ZXIgY29uc2lkZXJzIHRoaXMgRE8gYXMgY2FuZGlkYXRlIGZvciBicmVha3BvaW50IChuYW1lZCBwaXZvdERPIGluIHRoZSBzY3JpcHQpLiBBIHJlZ3Jlc3Npb24gaXMgdGhlbiBjYWxjdWxhdGVkIHVzaW5nIG9ic2VydmF0aW9ucyBhdCBETyBsZXZlbHMgXDwgcGl2b3RETywgYW5kIGEgZmlyc3QgZXN0aW1hdGUgb2YgTzxzdWI+MmNyaXQ8L3N1Yj4gaXMgY2FsY3VsYXRlZCBhcyB0aGUgaW50ZXJzZWN0aW9uIG9mIHRoaXMgcmVncmVzc2lvbiBsaW5lIHdpdGggdGhlIGhvcml6b250YWwgbGluZSByZXByZXNlbnRpbmcgU01SLiBUaGUgc2NyaXB0IHRoZW4gZ29lcyB0aHJvdWdoIHZhbGlkYXRpb24gc3RlcHMgdG8gZW5zdXJlIHRoYXQgdGhlIHNsb3BlIG9mIHRoZSByZWdyZXNzaW9uIGlzIG5vdCBzbyBsb3cgdGhhdCB0aGUgbGluZSwgcHJvamVjdGVkIHRvIG5vcm1veGljIERPIGxldmVscywgcGFzc2VzIGJlbG93IGFueSBNTzxzdWI+Mjwvc3ViPiB2YWx1ZXMgb2JzZXJ2ZWQgaW4gbm9ybW94aWEuIEl0IGFsc28gZW5zdXJlcyB0aGF0IHRoZSBpbnRlcmNlcHQgaXMgbm90IGdyZWF0ZXIgdGhhbiB6ZXJvLiBDb3JyZWN0aXZlIG1lYXN1cmVzIGFyZSB0YWtlbiBpZiBzdWNoIHByb2JsZW1zIGFyZSBlbmNvdW50ZXJlZC4gIA0KDQpsb3dlc3RNTzIgZGVmYXVsdCBpcyB0aGUgYHF1YW50aWxlKE1PMltETyA+PSA4MF0sIHA9MC4wNSlgLiBJdCBpcyB1c2VkIHRvIHNlZ21lbnQgdGhlIGRhdGEgYW5kIGxvY2F0ZSB0aGUgcGl2b3RETy4gIA0KDQpgYGB7cn0NCmlkcyA8LSBzbG9wZV90aWR5ICU+JSANCiAgZHBseXI6OmRpc3RpbmN0KGlkKSAlPiUgDQogIGRwbHlyOjpwdWxsKCkNCg0KcGNyaXRfbW9kZWxfZGZfbGlzdCA8LSBsaXN0KCkNCnBjcml0X21vZGVscyA8LSAgbGlzdCgpDQoNCmZvciAoaWRfaSBpbiBpZHMpIHsNCg0KZGZfaSA8LSBzbG9wZV90aWR5ICU+JSANCiAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKQ0KDQpvMmNyaXQgPC0gY2FsY08yY3JpdChEYXRhID0gZGZfaSwgU01SID0gZGZfaSRTTVJbMV0sIGxvd2VzdE1PMj1OQSwgZ2FwTGltaXQgPSA0LA0KICAgICAgICAgICAgICAgICAgICAgbWF4Lm5iLk1PMi5mb3IucmVnID0gNykNCg0KYmVzdF9tb2RfdHlwZSA8LSBiZXN0X21vZCAlPiUNCiAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogIHB1bGwobW9kZWxfdHlwZSkNCiAgDQp2YXVsZSA8LSBvMmNyaXQkbzJjcml0DQpsb3dlc3RNTzIgPSBxdWFudGlsZShkZl9pJE1PMltkZl9pJERPID49IDgwXSwgcD0wLjA1KQ0KU01SIDwtIG8yY3JpdCRTTVINCm5iX21vMl9jb25mb3JtaW5nIDwtIG8yY3JpdCROYl9NTzJfY29uZm9ybWluZw0KcjIgPC0gbzJjcml0JHIyDQptZXRob2QgPC0gbzJjcml0JE1ldGhvZA0KcCA8LSBvMmNyaXQkUFsxXQ0KbGV0aGFsX3BvaW50IDwtIG1pbihvMmNyaXQkbGV0aGFsUG9pbnRzKQ0KDQpwY3JpdF9tb2RlbF9kZiA8LSB0aWJibGUoDQogICAgICBpZCA9IGlkX2ksDQogICAgICBwY3JpdF92YXVsZSA9IHZhdWxlLA0KICAgICAgcGNyaXRfc21yID0gU01SLA0KICAgICAgcGNyaXRfbG93ZXN0TU8yID0gbG93ZXN0TU8yLA0KICAgICAgcGNyaXRfbmJfbW8yX2NvbmZvcm1pbmcgPSBuYl9tbzJfY29uZm9ybWluZywNCiAgICAgIHBjcml0X2xldGhhbF9wb2ludHMgPSBsZXRoYWxfcG9pbnQsDQogICAgICBwY3JpdF9yMiA9IHIyLA0KICAgICAgcGNyaXRfbWV0aG9kID0gbWV0aG9kLA0KICAgICAgcGNyaXRfcCA9IHAsDQogICAgICBiZXN0X21vZF90eXBlID0gYmVzdF9tb2RfdHlwZQ0KICAgICkNCg0KcGNyaXRfbW9kZWxfZGZfbGlzdFtbaWRfaV1dIDwtIHBjcml0X21vZGVsX2RmDQoNCnBjcml0X21vZGVsc1tbaWRfaV1dIDwtIG8yY3JpdA0KDQp9DQoNCnBjcml0X21vZGVsX2RmIDwtIGJpbmRfcm93cyhwY3JpdF9tb2RlbF9kZl9saXN0KQ0KYGBgDQoNCiMjIyBQbG90aW5nIE8yY3JpdA0KDQpIZXJlJ3Mgd2UgYXJlIHNhdmluZyBhbGwgTzxzdWI+MmNyaXQ8L3N1Yj4gbW9kZWxzLCBldmVuIHRob3NlIE1PPHN1Yj4yPC9zdWI+LU88c3ViPjI8L3N1Yj4gcmVsYXRpb25zaGlwcyBiZXN0IG1vZGVsbGVkIGJ5IDBedGheLSBhbmQgMV5zdF4tb3JkZXIgcG9seW5vbWlhbHMuDQoNCmBgYHtyfQ0KIyBDcmVhdGUgb3V0cHV0IGRpcmVjdG9yeSBpZiBuZWVkZWQNCm91dHB1dF9maWdfcGNyaXRfY2hhYm90X3dkIDwtIGZpbGUucGF0aChvdXRwdXRfZmlnX3dkLCAibW9kZWxfY2hhYm90IikNCmlmICghZGlyLmV4aXN0cyhvdXRwdXRfZmlnX3Bjcml0X2NoYWJvdF93ZCkpIHsNCiAgZGlyLmNyZWF0ZShvdXRwdXRfZmlnX3Bjcml0X2NoYWJvdF93ZCkNCn0NCg0KaWRzIDwtIHNsb3BlX3RpZHkgJT4lDQogIGRwbHlyOjpkaXN0aW5jdChpZCkgJT4lDQogIGRwbHlyOjpwdWxsKCkNCg0KcGNyaXRfY2hhYm90X2xpc3QgPC0gbGlzdCgpDQoNCiMgT3BlbiBhIHNpbmdsZSBQREYgZGV2aWNlDQpwZGYoZmlsZSA9IGZpbGUucGF0aChvdXRwdXRfZmlnX3Bjcml0X2NoYWJvdF93ZCwgImNvbWJpbmVkX2NoYWJvdF9wbG90cy5wZGYiKSwNCiAgICB3aWR0aCA9IDgsIGhlaWdodCA9IDYpDQoNCmZvciAoaWRfaSBpbiBpZHMpIHsNCg0KICBiZXN0X21vZF90eXBlIDwtIGJlc3RfbW9kICU+JQ0KICBkcGx5cjo6ZmlsdGVyKGlkID09IGlkX2kpICU+JQ0KICBwdWxsKG1vZGVsX3R5cGUpDQoNCiAgcjIgPC0gcGNyaXRfbW9kZWxfZGYgJT4lDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUNCiAgICBkcGx5cjo6bXV0YXRlKHBjcml0X3IyID0gcm91bmQocGNyaXRfcjIsIDMpKSAlPiUNCiAgICBkcGx5cjo6cHVsbChwY3JpdF9yMikNCg0KICBjb25mb3JtaW5nIDwtIHBjcml0X21vZGVsX2RmICU+JQ0KICAgIGRwbHlyOjpmaWx0ZXIoaWQgPT0gaWRfaSkgJT4lDQogICAgZHBseXI6Om11dGF0ZShwY3JpdF9uYl9tbzJfY29uZm9ybWluZyA9IHJvdW5kKHBjcml0X25iX21vMl9jb25mb3JtaW5nLCAzKSkgJT4lDQogICAgZHBseXI6OnB1bGwocGNyaXRfbmJfbW8yX2NvbmZvcm1pbmcpDQoNCiAgUCA8LSBwY3JpdF9tb2RlbF9kZiAlPiUNCiAgICBkcGx5cjo6ZmlsdGVyKGlkID09IGlkX2kpICU+JQ0KICAgIGRwbHlyOjptdXRhdGUocGNyaXRfcCA9IHJvdW5kKHBjcml0X3AsIDMpKSAlPiUNCiAgICBkcGx5cjo6cHVsbChwY3JpdF9wKQ0KDQogIFNNUiA8LSBwY3JpdF9tb2RlbF9kZiAlPiUNCiAgICBkcGx5cjo6ZmlsdGVyKGlkID09IGlkX2kpICU+JQ0KICAgIGRwbHlyOjptdXRhdGUocGNyaXRfc21yID0gcm91bmQocGNyaXRfc21yLCAzKSkgJT4lDQogICAgZHBseXI6OnB1bGwocGNyaXRfc21yKQ0KDQogIGxvd2VzdE1PMiA8LSBwY3JpdF9tb2RlbF9kZiAlPiUNCiAgICBkcGx5cjo6ZmlsdGVyKGlkID09IGlkX2kpICU+JQ0KICAgIGRwbHlyOjptdXRhdGUocGNyaXRfbG93ZXN0TU8yID0gcm91bmQocGNyaXRfbG93ZXN0TU8yLCAzKSkgJT4lDQogICAgZHBseXI6OnB1bGwocGNyaXRfbG93ZXN0TU8yKQ0KDQogICMgR2VuZXJhdGUgYW5kIHJlbmRlciB0aGUgcGxvdA0KICBwbG90TzJjcml0KG8yY3JpdG9iaiA9IHBjcml0X21vZGVsc1tbaWRfaV1dKQ0KDQogICMgQWRkIGEgdGl0bGUNCiAgbXRleHQoDQogICAgdGV4dCA9IHBhc3RlMChpZF9pKSwNCiAgICBzaWRlID0gMywgbGluZSA9IDIsIGFkaiA9IDAsDQogICAgY29sID0gImJsdWUiLCBmb250ID0gMiwgY2V4ID0gMS4yDQogICkNCg0KICBtdGV4dCgNCiAgICB0ZXh0ID0gcGFzdGUwKCJSMiA9ICIsIHIyLCAiOyBwID0gIiwgUCwgIjsgQ1AgPCBTTVIgPSAiLCBjb25mb3JtaW5nLCAiOyBTTVIgPSAiLCBTTVIsICI7IGxvd2VzdE1PMiA9ICIsbG93ZXN0TU8yKSwNCiAgICBzaWRlID0gMywgbGluZSA9IDEsIGFkaiA9IDAsDQogICAgY29sID0gImJsdWUiLCBmb250ID0gMSwgY2V4ID0gMC44DQogICkNCg0KICBtdGV4dCgNCiAgICB0ZXh0ID0gcGFzdGUwKCJCZXN0IG1vZGVsIGZpdCA9ICIsIGJlc3RfbW9kX3R5cGUpLA0KICAgIHNpZGUgPSAzLCBsaW5lID0gMCwgYWRqID0gMCwNCiAgICBjb2wgPSAicmVkIiwgZm9udCA9IDEsIGNleCA9IDAuOA0KICApDQp9DQoNCiMgQ2xvc2UgdGhlIFBERiBkZXZpY2UgKmFmdGVyKiB0aGUgbG9vcA0KZGV2Lm9mZigpDQpgYGANCg0KTm93IHByaW50aW5nIHRoZSBmaXNoIHRoYXQgd2VyZSBmaXR0ZWQgd2l0aCBoaWdoZXIgb3JkZXItcG9seW5vbWlhbHMgaW4gdGhlIGh0bG0gZG9jdW1lbnQNCg0KYGBge3IsIGZpZy5oZWlnaHQgPSAzLCBmaWcud2lkdGg9IDh9DQoNCnBhcihtZnJvdyA9IGMoMSwgMiksIG1hciA9IGMoNCwgNCwgNCwgMikpIA0KDQpwY3JpdF9tb2RlbF9tZXRhIDwtIHNsb3BlX3RpZHkgJT4lIA0KICBkcGx5cjo6Z3JvdXBfYnkoaWQpICU+JSANCiAgZHBseXI6OnNsaWNlKDEpICU+JSANCiAgZHBseXI6OnVuZ3JvdXAoKSAlPiUgDQogIGRwbHlyOjpsZWZ0X2pvaW4ocGNyaXRfbW9kZWxfZGYsIC4sIGJ5ID0gImlkIikNCg0KaGlnaGVyX29yZGVyX2lkcyA8LSAgcGNyaXRfbW9kZWxfbWV0YSAlPiUgDQogIGRwbHlyOjpmaWx0ZXIoYmVzdF9tb2RfdHlwZSA9PSAibG1fMiIgfCBiZXN0X21vZF90eXBlID09ICJsbV8zIikgJT4lIA0KICBkcGx5cjo6ZGlzdGluY3QoaWQpICU+JSANCiAgZHBseXI6OnB1bGwoKQ0KDQpmb3IgKGlkX2kgaW4gaGlnaGVyX29yZGVyX2lkcykgew0KICANCiAgDQogIHIyIDwtIHBjcml0X21vZGVsX21ldGEgJT4lIA0KICAgIGRwbHlyOjpmaWx0ZXIoaWQgPT0gaWRfaSkgJT4lIA0KICAgIGRwbHlyOjptdXRhdGUocGNyaXRfcjIgPSByb3VuZChwY3JpdF9yMiwgMykpICU+JSANCiAgICBkcGx5cjo6cHVsbChwY3JpdF9yMikNCiAgDQogIGNvbmZvcm1pbmcgPC0gcGNyaXRfbW9kZWxfbWV0YSAlPiUgDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogICAgZHBseXI6Om11dGF0ZShwY3JpdF9uYl9tbzJfY29uZm9ybWluZyA9IHJvdW5kKHBjcml0X25iX21vMl9jb25mb3JtaW5nLCAzKSkgJT4lIA0KICAgIGRwbHlyOjpwdWxsKHBjcml0X25iX21vMl9jb25mb3JtaW5nKQ0KICANCiAgUCA8LSBwY3JpdF9tb2RlbF9tZXRhICU+JSANCiAgICBkcGx5cjo6ZmlsdGVyKGlkID09IGlkX2kpICU+JSANCiAgICBkcGx5cjo6bXV0YXRlKHBjcml0X3AgPSByb3VuZChwY3JpdF9wLCAzKSkgJT4lIA0KICAgIGRwbHlyOjpwdWxsKHBjcml0X3ApDQogIA0KICBTTVIgPC0gcGNyaXRfbW9kZWxfbWV0YSAlPiUgDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogICAgZHBseXI6Om11dGF0ZShwY3JpdF9zbXIgPSByb3VuZChwY3JpdF9zbXIsIDMpKSAlPiUgDQogICAgZHBseXI6OnB1bGwocGNyaXRfc21yKQ0KICANCiAgbG93ZXN0TU8yIDwtIHBjcml0X21vZGVsX21ldGEgJT4lIA0KICAgIGRwbHlyOjpmaWx0ZXIoaWQgPT0gaWRfaSkgJT4lIA0KICAgIGRwbHlyOjptdXRhdGUocGNyaXRfbG93ZXN0TU8yID0gcm91bmQocGNyaXRfbG93ZXN0TU8yLCAzKSkgJT4lIA0KICAgIGRwbHlyOjpwdWxsKHBjcml0X2xvd2VzdE1PMikNCiAgDQogICMgR2VuZXJhdGUgYW5kIHJlbmRlciB0aGUgcGxvdA0KICBwbG90TzJjcml0KG8yY3JpdG9iaiA9IHBjcml0X21vZGVsc1tbaWRfaV1dKQ0KICANCiAgIyBBZGQgYSB0aXRsZQ0KICBtdGV4dCgNCiAgICB0ZXh0ID0gcGFzdGUwKGlkX2kpLA0KICAgIHNpZGUgPSAzLCBsaW5lID0gMiwgYWRqID0gMCwNCiAgICBjb2wgPSAiYmx1ZSIsIGZvbnQgPSAyLCBjZXggPSAxLjINCiAgKQ0KICANCiAgbXRleHQoDQogICAgdGV4dCA9IHBhc3RlMCgiUjIgPSAiLCByMiwgIjsgcCA9ICIsIFAsICI7IENQIDwgU01SID0gIiwgY29uZm9ybWluZyksDQogICAgc2lkZSA9IDMsIGxpbmUgPSAxLCBhZGogPSAwLA0KICAgIGNvbCA9ICJibHVlIiwgZm9udCA9IDAuNSwgY2V4ID0gMC44DQogICkNCiAgDQogICBtdGV4dCgNCiAgICB0ZXh0ID0gcGFzdGUwKCJTTVIgPSAiLCBTTVIsICI7IGxvd2VzdE1PMiA9ICIsbG93ZXN0TU8yKSwNCiAgICBzaWRlID0gMywgbGluZSA9IDAsIGFkaiA9IDAsDQogICAgY29sID0gImJsdWUiLCBmb250ID0gMC41LCBjZXggPSAwLjgNCiAgKQ0KfQ0KYGBgDQoNCg0KIyMjIE/igoJjcml0IG51bWVyaWNhbCBydWxlcw0KDQpXZSBhcHBsaWVkIGEgbnVtZXJpY2FsIHJ1bGUgdG8gYXNzZXMgaWYgYSBPPHN1Yj4yY3JpdDwvc3ViPiB3YXMgb2JzZXJ2ZWQuIFNwZWNpZmljYWxseSwgd2UgZmlsdGVyZWQgZm9yIG9ubHkgY2FzZXMgd2VyZSBhdCB0aGUgbG93ZXN0IE/igoIgdmFsdWUgdGhyZWUgY29uc2VjdXRpdmUgTU/igoIgbWVhc3VyZXMgZnVsbCBiZWxvdyBvdXIgU01SIGFuZCBmaWZ0aCBwZXJjZW50aWxlIG9mIHRoZSBNTzIgdmFsdWVzIG9ic2VydmVkIGF0IGRpc3NvbHZlZCBPMiBsZXZlbHMgPiA4MCUuIEluIHRoZSBtb2RlbCBvdXRwdXQgdGhlc2UgYXJlIGNhbGxlZCBuYl9tbzJfY29uZm9ybWluZyBwb2ludHMuDQoNCmBgYHtyfQ0KbzJjcml0X251bWVyaWNhbF95ZXMgPC0gcGNyaXRfbW9kZWxfZGYgJT4lIA0KICBkcGx5cjo6ZmlsdGVyKHBjcml0X25iX21vMl9jb25mb3JtaW5nID4gMikgJT4lIA0KICBwdWxsKGlkKQ0KDQpwYXN0ZTAoIkJhc2VkIG9uIHRoaXMgcnVsZSB0aGVyZSBhcmUgIiwgbGVuZ3RoKG8yY3JpdF9udW1lcmljYWxfeWVzKSwgIiBmaXNoIHdpdGggcG9zc2libGUgT+KCgmNyaXRzLiIpDQpgYGANCg0KDQojIyMjIEZpZ3VyZSBTNg0KDQpQbG90dGluZyBmaXNoIHRoYXQgbWVldCBvdXIgbnVtZXJpY2FsIHJ1bGUgZm9yIE88c3ViPjJjcml0PC9zdWI+IA0KDQpgYGB7ciwgZmlnLmhlaWdodCA9IDMsIGZpZy53aWR0aD0gOH0NCg0KcGFyKG1mcm93ID0gYygxLCAyKSwgbWFyID0gYyg0LCA0LCA0LCAyKSkgDQoNCmZvciAoaWRfaSBpbiBvMmNyaXRfbnVtZXJpY2FsX3llcykgew0KICANCiAgDQogIHIyIDwtIHBjcml0X21vZGVsX21ldGEgJT4lIA0KICAgIGRwbHlyOjpmaWx0ZXIoaWQgPT0gaWRfaSkgJT4lIA0KICAgIGRwbHlyOjptdXRhdGUocGNyaXRfcjIgPSByb3VuZChwY3JpdF9yMiwgMykpICU+JSANCiAgICBkcGx5cjo6cHVsbChwY3JpdF9yMikNCiAgDQogIGNvbmZvcm1pbmcgPC0gcGNyaXRfbW9kZWxfbWV0YSAlPiUgDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogICAgZHBseXI6Om11dGF0ZShwY3JpdF9uYl9tbzJfY29uZm9ybWluZyA9IHJvdW5kKHBjcml0X25iX21vMl9jb25mb3JtaW5nLCAzKSkgJT4lIA0KICAgIGRwbHlyOjpwdWxsKHBjcml0X25iX21vMl9jb25mb3JtaW5nKQ0KICANCiAgUCA8LSBwY3JpdF9tb2RlbF9tZXRhICU+JSANCiAgICBkcGx5cjo6ZmlsdGVyKGlkID09IGlkX2kpICU+JSANCiAgICBkcGx5cjo6bXV0YXRlKHBjcml0X3AgPSByb3VuZChwY3JpdF9wLCAzKSkgJT4lIA0KICAgIGRwbHlyOjpwdWxsKHBjcml0X3ApDQogIA0KICBTTVIgPC0gcGNyaXRfbW9kZWxfbWV0YSAlPiUgDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogICAgZHBseXI6Om11dGF0ZShwY3JpdF9zbXIgPSByb3VuZChwY3JpdF9zbXIsIDMpKSAlPiUgDQogICAgZHBseXI6OnB1bGwocGNyaXRfc21yKQ0KICANCiAgbG93ZXN0TU8yIDwtIHBjcml0X21vZGVsX21ldGEgJT4lIA0KICAgIGRwbHlyOjpmaWx0ZXIoaWQgPT0gaWRfaSkgJT4lIA0KICAgIGRwbHlyOjptdXRhdGUocGNyaXRfbG93ZXN0TU8yID0gcm91bmQocGNyaXRfbG93ZXN0TU8yLCAzKSkgJT4lIA0KICAgIGRwbHlyOjpwdWxsKHBjcml0X2xvd2VzdE1PMikNCiAgDQogICMgR2VuZXJhdGUgYW5kIHJlbmRlciB0aGUgcGxvdA0KICBwbG90TzJjcml0KG8yY3JpdG9iaiA9IHBjcml0X21vZGVsc1tbaWRfaV1dKQ0KICANCiAgIyBBZGQgYSB0aXRsZQ0KICBtdGV4dCgNCiAgICB0ZXh0ID0gcGFzdGUwKGlkX2kpLA0KICAgIHNpZGUgPSAzLCBsaW5lID0gMiwgYWRqID0gMCwNCiAgICBjb2wgPSAiYmx1ZSIsIGZvbnQgPSAyLCBjZXggPSAxLjINCiAgKQ0KICANCiAgbXRleHQoDQogICAgdGV4dCA9IHBhc3RlMCgiUjIgPSAiLCByMiwgIjsgcCA9ICIsIFAsICI7IENQIDwgU01SID0gIiwgY29uZm9ybWluZyksDQogICAgc2lkZSA9IDMsIGxpbmUgPSAxLCBhZGogPSAwLA0KICAgIGNvbCA9ICJibHVlIiwgZm9udCA9IDAuNSwgY2V4ID0gMC44DQogICkNCiAgDQogICBtdGV4dCgNCiAgICB0ZXh0ID0gcGFzdGUwKCJTTVIgPSAiLCBTTVIsICI7IGxvd2VzdE1PMiA9ICIsbG93ZXN0TU8yKSwNCiAgICBzaWRlID0gMywgbGluZSA9IDAsIGFkaiA9IDAsDQogICAgY29sID0gImJsdWUiLCBmb250ID0gMC41LCBjZXggPSAwLjgNCiAgKQ0KfQ0KYGBgDQoNCioqRmlndXJlIFM2Kio6IFJlcHJlc2VudGF0aXZlIGV4YW1wbGVzIG9mIGZpc2ggdGhhdCB3ZXJlIGJlc3QgbW9kZWxsZWQgYnkgYSAybmQtIG9yIDNyZC1vcmRlciBwb2x5bm9taWFsIGFuZCBtZWV0IHRoZSBudW1lcmljYWwgaW5jbHVzaW9uIGNyaXRlcmlhLiBUaGUgaG9yaXpvbnRhbCBzb2xpZCBvcmFuZ2UgbGluZSBzaG93cyB0aGUgc3RhbmRhcmQgbWV0YWJvbGljIHJhdGUgKFNNUiksIHRoZSBob3Jpem9udGFsIHNvbGlkIHBpbmsgbGluZSBzaG93cyB0aGVsb3dlc3RNTzIgKGFzIGRlZmluZWQgYnkgIENsYWlyZWF1eCBhbmQgQ2hhYm90ICgyMDE2KSksIHRoZSBzb2xpZC9kYXNoZWQgYmx1ZS9ncmVlbiBzbG9wZSBsaW5lIHNob3dzIHRoZSBPMiByZWd1bGF0aW9uIGZhaWx1cmUgcmVncmVzc2lvbiAoYmFzZWQgb24gdGhlIHJ1bGUtYmFzZWQgbGluZWFyIHJlZ3Jlc3Npb24gbWV0aG9kIG9mIENsYWlyZWF1eCBhbmQgQ2hhYm90ICgyMDE2KTsgd2hlcmUgdGhlIGNvbG91ciBhbmQgbGluZSB0eXBlIGluZGljYXRlIHRoZSB0eXBlIG9mIHJlZ3Jlc3Npb24gZml0dGVkLCB0aHJvdWdoIG9yZ2luIG9yIG5vdCksIGFuZCB0aGUgc29saWQgdmVydGljYWwgYmx1ZS9ncmVlbiBsaW5lIHNob3dzIHRoZSBPMmNyaXQgZXN0aW1hdGUgKGludGVyc2VjdGlvbiBvZiBPMiBmYWlsdXJlIHJlZ3Jlc3Npb24gYW5kIFNNUikuDQoNCkhvdyBtYW55IGZyb20gZWFjaCBzYWxpbml0eSB0cmVhdG1lbnQNCg0KYGBge3J9DQpzbG9wZV90aWR5ICU+JSANCiAgZHBseXI6OmZpbHRlcihpZCAlaW4lIG8yY3JpdF9udW1lcmljYWxfeWVzKSAlPiUgDQogIGRwbHlyOjpncm91cF9ieShpZCkgJT4lIA0KICBkcGx5cjo6c2xpY2UoMSkgJT4lIA0KICBkcGx5cjo6dW5ncm91cCgpICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KHNhbGluaXR5X2dyb3VwKSAlPiUgDQogIGRwbHlyOjpyZWZyYW1lKG4gPSBsZW5ndGggKGlkKSkgJT4lIA0KICBkcGx5cjo6dW5ncm91cCgpICU+JSANCiAgZ3QoKQ0KYGBgDQoNCiMjIyBWaXN1YWwgaW5zcGVjdGlvbg0KDQpXZSBjb25kdWN0ZWQgdmlzdWFsIGluc3BlY3Rpb24gb2YgYWxsIDU4IGZpc2ggdG8gZGV0ZXJtaW5lIGlmIE88c3ViPjJjcml0czwvc3ViPiB3ZXJlIHByZXNlbnQuIFdlIGhhdmUgbG9hZGVkIHRoaXMgYXMgYSBkYXRhIGZyYW1lICoq8J+SvyBvMmNyaXRfY2hlY2sqKg0KDQpGb3IgdGhpcyB2aXN1YWwgaW5zcGVjdGlvbiwgd2UgZ3JvdXBlZCBmaXNoIGludG8gIm5vIiwgIm1heWJlIiBvciAieWVzIiwgYmFzZWQgb24gdGhlIGNlcnRhaW50eSBhdCB3aGljaCB3ZSBvYnNlcnZlZCBhIE88c3ViPjJjcml0czwvc3ViPi4gSW4gdGhlIGNhc2Ugb2YgeWVzIG9yIG1heWJlLCB3ZSBhbHNvIGVzdGltYXRlIGRpc3NvbHZlZCBveHlnZW4gcGVyY2VudGFnZS4gQWxsIGF1dGhvcnMgZGlkIHRoaXMgaW5kZXBlbmRlbnRseS4gIA0KDQojIyMjIPCfk4ggUmVzdWx0cw0KDQpMZXQncyBmaWd1cmUgb3V0IGhvdyBjb25zaXN0ZW50IHRoZSBjYXRlZ29yaXNhdGlvbiB3YXMsIGFuZCB3aGF0IHRoZSBtYWpvcml0eSByZXNwb25zZSB3YXMuIFRoZXJlIHdlcmUgMzUgY2FzZXMgd2l0aCBubyBkaXNhZ3JlZW1lbnRzICg2MC4zNCUpLCAyMyBjYXNlcyB3aXRoIG9uZSBvciBtb3JlIGRpc2FncmVlbWVudHMgKDM5LjY2JSkuICANCg0KYGBge3J9DQpkaXNhZ3JlZW1lbnRfc3VtbWFyeSA8LSBvMmNyaXRfY2hlY2sgJT4lDQogIGdyb3VwX2J5KGlkKSAlPiUNCiAgZHBseXI6OnJlZnJhbWUoDQogICAgbl9kaXNhZ3JlZW1lbnQgPSBuX2Rpc3RpbmN0KHBjcml0X2NhdCktMSwNCiAgICBjYXRfZGlzYWdyZWVtZW50ID0gaWZfZWxzZShuX2Rpc2FncmVlbWVudD09MCwgMCwgMSksDQogICAgbWFqb3JpdHlfY2F0ID0gbmFtZXMoc29ydCh0YWJsZShwY3JpdF9jYXQpLCBkZWNyZWFzaW5nID0gVFJVRSkpWzFdLA0KICAgIGNlcnRhaW50eSA9IG1heCh0YWJsZShwY3JpdF9jYXQpLzUqMTAwKQ0KICApDQoNCnRvdGFsX2Fzc2VzbWVudCA8LSBvMmNyaXRfY2hlY2sgJT4lIA0KICBkaXN0aW5jdChpZCkgJT4lIA0KICBucm93KCkNCg0KZGlzYWdyZWVtZW50X3N1bW1hcnkgJT4lDQogIGdyb3VwX2J5KGNhdF9kaXNhZ3JlZW1lbnQpICU+JSANCiAgZHBseXI6OnJlZnJhbWUoDQogICAgbiA9IGxlbmd0aChpZCksDQogICAgcGVyY2VudCA9IHJvdW5kKG4vdG90YWxfYXNzZXNtZW50KjEwMCwyKQ0KICApICU+JSANCiAgZ3QoKQ0KYGBgDQoNCiMjIyMgRmlndXJlIFM3DQoNCkhlcmUncyBhIGhlYXQgbWFwIHRvIHNob3cgZGVjaXNpb25zIGZvciBlYWNoIGZpc2gNCg0KYGBge3IsIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD01fQ0KIyBEZWZpbmUgY3VzdG9tIGNvbG91cnMgZm9yIHBjcml0X2NhdA0KY2F0ZWdvcnlfY29sb3VycyA8LSBjKA0KICAibm8iID0gIiNFMDNDMzIiLA0KICAibWF5YmUiID0gIiNGRkQzMDEiLA0KICAieWVzIiA9ICIjN0JCNjYyIg0KKQ0KDQojIENyZWF0ZSBoZWF0bWFwDQpnZ3Bsb3QobzJjcml0X2NoZWNrLCBhZXMoeCA9IGV4cGVydCwgeSA9IGlkLCBmaWxsID0gcGNyaXRfY2F0KSkgKw0KICBnZW9tX3RpbGUoY29sb3VyID0gIndoaXRlIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjYXRlZ29yeV9jb2xvdXJzLCBuYS52YWx1ZSA9ICJncmV5OTAiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiVmlzdWFsIEFzc2Vzc21lbnQgb2YgcGNyaXRfY2F0IGJ5IEV4cGVydCBhbmQgSUQiLA0KICAgIHggPSAiRXhwZXJ0IiwNCiAgICB5ID0gIkZpc2ggSUQiLA0KICAgIGZpbGwgPSAiQ2F0ZWdvcnkiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gNyksICMgYWRqdXN0IHNpemUgYXMgbmVlZGVkDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpDQogICkNCmBgYA0KDQoNCioqRmlndXJlIFM3Kio6IEhlYXRtYXAgc2hvd2luZyB0aGUgdmlzdWFsIGFzc2Vzc21lbnQgb2YgY3JpdGljYWwgb3h5Z2VuIHNhdHVyYXRpb24gKE88c3ViPjJjcml0czwvc3ViPikgY2F0ZWdvcnkgKCJubyIsICJtYXliZSIgb3IgInllcyIpIGZvciBlYWNoIGZpc2ggYnkgZXhwZXJ0IGFzc2Vzc29yIChFbGl6YWJldGggQy4gSG9vdHMgW2VjaF0sIEpha2UgTS4gTWFydGluIFtqbW1dLCBMdWlzIEwuIEt1Y2hlbm3DvGxsZSBbbGxrXSBNYXJ5YW5lIEdyYWRpdG8gW21nXSwgVGltb3RoeSBELiBDbGFyayBbdGRjXSkuIEVhY2ggdGlsZSByZXByZXNlbnRzIG9uZSBmaXNoLWV4cGVydCBwYWlyaW5nLCBjb2xvdXItY29kZWQgYnkgYXNzaWduZWQgY2F0ZWdvcnk6DQo8c3BhbiBzdHlsZT0iY29sb3I6I0UwM0MzMiI+PHN0cm9uZz5ubzwvc3Ryb25nPjwvc3Bhbj4gKHJlZCwgI0UwM0MzMiksDQo8c3BhbiBzdHlsZT0iY29sb3I6I0ZGRDMwMSI+PHN0cm9uZz5tYXliZTwvc3Ryb25nPjwvc3Bhbj4gKHllbGxvdywgI0ZGRDMwMSksIGFuZA0KPHNwYW4gc3R5bGU9ImNvbG9yOiM3QkI2NjIiPjxzdHJvbmc+eWVzPC9zdHJvbmc+PC9zcGFuPiAoZ3JlZW4sICM3QkI2NjIpLg0KDQpFeHBlcnQgZGV2aWF0aW9uIGZyb20gdGhlIG1ham9yaXR5IGFzc2Vzc21lbnQgcmFuZ2VkIGZyb20gMjIuNDEgdG8gNi45MCUuDQoNCmBgYHtyfQ0KbzJjcml0X2NoZWNrX3N1bSA8LSBvMmNyaXRfY2hlY2sgJT4lIA0KICBkcGx5cjo6bGVmdF9qb2luKC4sIGRpc2FncmVlbWVudF9zdW1tYXJ5LCBieSA9ICJpZCIpICU+JSANCiAgZHBseXI6Om11dGF0ZShkZXZpYXRlZCA9IGlmX2Vsc2UocGNyaXRfY2F0ICE9IG1ham9yaXR5X2NhdCwgMSwgMCkpDQoNCm8yY3JpdF9jaGVja19zdW0gJT4lDQogIGdyb3VwX2J5KGV4cGVydCkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBkZXZpYXRpb25zID0gc3VtKGRldmlhdGVkKSwNCiAgICBkZXZpYXRpb25fcmF0ZSA9IHJvdW5kKGRldmlhdGlvbnMgLyA1OCAqIDEwMCwgMikNCiAgKSAlPiUgDQogIGRwbHlyOjphcnJhbmdlKGRlc2MoZGV2aWF0aW9ucykpICU+JSANCiAgZ3QoKQ0KYGBgDQoNCkxldCdzIG1ha2UgYSBsaXN0IG9mIHRob3NlIHRoYXQgaGFkIG1ham9yaXR5IGFzc2lnbmVkIGFzIHllcyBmb3IgYW4gTzxzdWI+MmNyaXQ8L3N1Yj4uIFRoZXJlIHdhcyAxMCB0b3RhbC4gIA0KDQpgYGB7cn0NCm8yY3JpdF92aXN1YWxfeWVzIDwtICBkaXNhZ3JlZW1lbnRfc3VtbWFyeSAlPiUgDQogIGRwbHlyOjpmaWx0ZXIobWFqb3JpdHlfY2F0ID09ICJ5ZXMiKSAlPiUgDQogIGRwbHlyOjpwdWxsKGlkKQ0KDQpwYXN0ZTAoIkJhc2VkIG9uIHRoZSBtYWpvcml0eSB2aXN1YWwgYXNzZXNzbWVudCAiLCBsZW5ndGgobzJjcml0X3Zpc3VhbF95ZXMpLCAiIGZpc2ggaGF2ZSBwb3NzaWJsZSBP4oKCY3JpdC4iKQ0KYGBgDQoNCiMjIyBP4oKCY3JpdCBudW1iZXJzDQoNCldlIHdpbGwgbm93IGNoZWNrIHRvIHNlZSB3aGljaCBmaXNoIGhhdmUgTzxzdWI+MmNyaXQ8L3N1Yj4gYmFzZWQgb24gdGhlIG51bWVyaWNhbCBhbmQgdmlzdWFsIGluc3BlY3Rpb25zLiAgIA0KDQpUaGVyZSBhcmUgZWlnaHQgZmlzaCB0aGF0IGJvdGggbnVtZXJpY2FsbHkgYW5kIHZpc3VhbGx5IHdlcmUgZGV0ZXJtaW5lZCB0byBoYXZlIGEgTzxzdWI+MmNyaXQ8L3N1Yj4uIFR3byBmaXNoIHdpdGggYSB2aXN1YWxseSBjb25maXJtZWQgTzxzdWI+MmNyaXQ8L3N1Yj4sIHRoYXQgZGlkIG5vdCBtZWV0IHRoZSBudW1lcmljYWwgY3JpdGVyaWEuIEVpZ2h0IGZpc2ggbWVldCB0aGUgbnVtZXJpY2FsIGNyaXRlcmlhLCBidXQgZGlkIG5vdCBwYXNzIHRoZSB2aXN1YWwgaW5zcGVjdGlvbi4gIA0KDQpgYGB7cn0NCnNoYXJlZF9lbGVtZW50cyA8LSBpbnRlcnNlY3QobzJjcml0X3Zpc3VhbF95ZXMsIG8yY3JpdF9udW1lcmljYWxfeWVzKQ0KDQp1bmlxdWVfdG9fdmlzdWFsIDwtIHNldGRpZmYobzJjcml0X3Zpc3VhbF95ZXMsIG8yY3JpdF9udW1lcmljYWxfeWVzKQ0KDQp1bmlxdWVfdG9fbnVtZXJpY2FsIDwtIHNldGRpZmYobzJjcml0X251bWVyaWNhbF95ZXMsIG8yY3JpdF92aXN1YWxfeWVzKQ0KDQpsaXN0KA0KICBTaGFyZWQgPSBzaGFyZWRfZWxlbWVudHMsDQogIFVuaXF1ZV90b192aXN1YWwgPSB1bmlxdWVfdG9fdmlzdWFsLA0KICBVbmlxdWVfdG9fbnVtZXJpY2FsID0gdW5pcXVlX3RvX251bWVyaWNhbA0KKQ0KYGBgDQoNCkhvdyBtYW55IHBlciBzYWxpbml0eSB0cmVhdG1lbnQgDQoNCmBgYHtyfQ0Kc2xvcGVfdGlkeSAlPiUgDQogIGRwbHlyOjpmaWx0ZXIoaWQgJWluJSBzaGFyZWRfZWxlbWVudHMpICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KGlkKSAlPiUgDQogIGRwbHlyOjpzbGljZSgxKSAlPiUgDQogIGRwbHlyOjp1bmdyb3VwKCkgJT4lIA0KICBkcGx5cjo6Z3JvdXBfYnkoc2FsaW5pdHlfZ3JvdXApICU+JSANCiAgZHBseXI6OnJlZnJhbWUobiA9IGxlbmd0aCAoaWQpKSAlPiUgDQogIGRwbHlyOjp1bmdyb3VwKCkgJT4lIA0KICBndCgpDQpgYGANCg0KDQojIyMjIPCfk4ggUmVzdWx0cw0KDQpMb29raW5nIGF0IG1lYW4gTzxzdWI+MmNyaXQ8L3N1Yj4gZXN0aW1hdGVzLiAgIA0KDQpgYGB7cn0NCnBvcF9tYXNzIDwtIHBjcml0X21vZGVsX21ldGEgJT4lIA0KICBkcGx5cjo6cmVmcmFtZSgNCiAgICBtZWFuX21hc3MgPSBtZWFuKG1hc3MpDQogICkgJT4lIA0KICBwdWxsKG1lYW5fbWFzcykNCg0KcGNyaXRfbW9kZWxfbWV0YSAlPiUgDQogIGRwbHlyOjpmaWx0ZXIoaWQgJWluJSBzaGFyZWRfZWxlbWVudHMpICU+JSANCiAgZHBseXI6Om11dGF0ZShyZWxfbWFzcyA9IG1hc3MvcG9wX21hc3MpICU+JSANCiAgZHBseXI6OnJlZnJhbWUoDQogICAgbl9vMmNyaXQgPSBsZW5ndGgocGNyaXRfdmF1bGUpLA0KICAgIG1lYW5fbzJjcml0ID0gbWVhbihwY3JpdF92YXVsZSksDQogICAgbWluX28yY3JpdCA9IG1pbihwY3JpdF92YXVsZSksDQogICAgbWF4X28yY3JpdCA9IG1heChwY3JpdF92YXVsZSksDQogICAgbWVhbl9tYXNzID0gbWVhbihtYXNzKSwNCiAgICBtZWFuX3JlbF9tYXNzID0gbWVhbiAocmVsX21hc3MpLA0KICAgIHNkX21hc3MgPSBzZChtYXNzKSwNCiAgICBzZF9yZWxfbWFzcyA9IHNkKHJlbF9tYXNzKQ0KICApICU+JSANCiAgZ3QoKSAlPiUgDQogICAgZm10X251bWJlcigNCiAgICBjb2x1bW5zID0gd2hlcmUoaXMubnVtZXJpYyksDQogICAgZGVjaW1hbHMgPSAyDQogICkNCmBgYA0KDQoNCmBgYHtyfQ0KbWluX2RvcyA8LSBzbG9wZV90aWR5ICU+JSANCiAgZHBseXI6OmZpbHRlcighKGlkICVpbiUgc2hhcmVkX2VsZW1lbnRzKSkgJT4lDQogIGdyb3VwX2J5KGlkKSAlPiUgDQogIGRwbHlyOjpyZWZyYW1lKA0KICAgIG1pbl9kbyA9IG1pbihETykNCiAgKQ0KDQptaW5fZG9zICU+JSANCiAgZHBseXI6OnJlZnJhbWUoDQogICAgbWVhbl9taW5fZG8gPSByb3VuZChtZWFuKG1pbl9kbyksMiksDQogICAgc2RfbWluX2RvID0gcm91bmQoc2QobWluX2RvKSwyKSwNCiAgICBtaW5fbWluX2RvID0gcm91bmQobWluKG1pbl9kbyksMikNCiAgKSAlPiUgDQogIGd0KCkNCmBgYA0KDQoNCg0KDQpgYGB7cn0NCnBjcml0X21vZGVsX21ldGEgJT4lIA0KICBkcGx5cjo6ZmlsdGVyKGlkICVpbiUgc2hhcmVkX2VsZW1lbnRzKSAlPiUgDQogIGRwbHlyOjpncm91cF9ieShzYWxpbml0eV9ncm91cCkgJT4lIA0KICBkcGx5cjo6cmVmcmFtZSgNCiAgICBuX28yY3JpdCA9IGxlbmd0aChwY3JpdF92YXVsZSksDQogICAgbWVhbl9vMmNyaXQgPSBtZWFuKHBjcml0X3ZhdWxlKSwNCiAgICBtaW5fbzJjcml0ID0gbWluKHBjcml0X3ZhdWxlKSwNCiAgICBtYXhfbzJjcml0ID0gbWF4KHBjcml0X3ZhdWxlKSwNCiAgICBtZWFuX21hc3MgPSBtZWFuKG1hc3MpDQogICkgJT4lIA0KICBndCgpDQpgYGANCg0KIyMjIEZpZ3VyZSBTOA0KDQpUaGVzZSBhcmUgdGhlIDggZmlzaCB0aGF0IG1lZXQgbnVtZXJpY2FsIGNyaXRlcmlhIGFuZCBwYXNzZWQgdmlzdWFsIGluc3BlY3Rpb24uDQoNCmBgYHtyLCBmaWcuaGVpZ2h0ID0gMywgZmlnLndpZHRoPSA4fQ0KDQpwYXIobWZyb3cgPSBjKDEsIDIpLCBtYXIgPSBjKDQsIDQsIDQsIDIpKSANCg0KZm9yIChpZF9pIGluIHNoYXJlZF9lbGVtZW50cykgew0KICANCiAgcjIgPC0gcGNyaXRfbW9kZWxfbWV0YSAlPiUgDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogICAgZHBseXI6Om11dGF0ZShwY3JpdF9yMiA9IHJvdW5kKHBjcml0X3IyLCAzKSkgJT4lIA0KICAgIGRwbHlyOjpwdWxsKHBjcml0X3IyKQ0KICANCiAgY29uZm9ybWluZyA8LSBwY3JpdF9tb2RlbF9tZXRhICU+JSANCiAgICBkcGx5cjo6ZmlsdGVyKGlkID09IGlkX2kpICU+JSANCiAgICBkcGx5cjo6bXV0YXRlKHBjcml0X25iX21vMl9jb25mb3JtaW5nID0gcm91bmQocGNyaXRfbmJfbW8yX2NvbmZvcm1pbmcsIDMpKSAlPiUgDQogICAgZHBseXI6OnB1bGwocGNyaXRfbmJfbW8yX2NvbmZvcm1pbmcpDQogIA0KICBQIDwtIHBjcml0X21vZGVsX21ldGEgJT4lIA0KICAgIGRwbHlyOjpmaWx0ZXIoaWQgPT0gaWRfaSkgJT4lIA0KICAgIGRwbHlyOjptdXRhdGUocGNyaXRfcCA9IHJvdW5kKHBjcml0X3AsIDMpKSAlPiUgDQogICAgZHBseXI6OnB1bGwocGNyaXRfcCkNCiAgDQogIFNNUiA8LSBwY3JpdF9tb2RlbF9tZXRhICU+JSANCiAgICBkcGx5cjo6ZmlsdGVyKGlkID09IGlkX2kpICU+JSANCiAgICBkcGx5cjo6bXV0YXRlKHBjcml0X3NtciA9IHJvdW5kKHBjcml0X3NtciwgMykpICU+JSANCiAgICBkcGx5cjo6cHVsbChwY3JpdF9zbXIpDQogIA0KICBsb3dlc3RNTzIgPC0gcGNyaXRfbW9kZWxfbWV0YSAlPiUgDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogICAgZHBseXI6Om11dGF0ZShwY3JpdF9sb3dlc3RNTzIgPSByb3VuZChwY3JpdF9sb3dlc3RNTzIsIDMpKSAlPiUgDQogICAgZHBseXI6OnB1bGwocGNyaXRfbG93ZXN0TU8yKQ0KICANCiAgIyBHZW5lcmF0ZSBhbmQgcmVuZGVyIHRoZSBwbG90DQogIHBsb3RPMmNyaXQobzJjcml0b2JqID0gcGNyaXRfbW9kZWxzW1tpZF9pXV0pDQogIA0KICAjIEFkZCBhIHRpdGxlDQogIG10ZXh0KA0KICAgIHRleHQgPSBwYXN0ZTAoaWRfaSksDQogICAgc2lkZSA9IDMsIGxpbmUgPSAyLCBhZGogPSAwLA0KICAgIGNvbCA9ICJibHVlIiwgZm9udCA9IDIsIGNleCA9IDEuMg0KICApDQogIA0KICBtdGV4dCgNCiAgICB0ZXh0ID0gcGFzdGUwKCJSMiA9ICIsIHIyLCAiOyBwID0gIiwgUCwgIjsgQ1AgPCBTTVIgPSAiLCBjb25mb3JtaW5nLCAiOyBTTVIgPSAiLCBTTVIsICI7IGxvd2VzdE1PMiA9ICIsbG93ZXN0TU8yKSwNCiAgICBzaWRlID0gMywgbGluZSA9IDEsIGFkaiA9IDAsDQogICAgY29sID0gImJsdWUiLCBmb250ID0gMSwgY2V4ID0gMC44DQogICkNCn0NCmBgYA0KDQoqKkZpZ3VyZSBTOCoqOiBSZXByZXNlbnRhdGl2ZSBleGFtcGxlcyBvZiBmaXNoIHRoYXQgd2VyZSBiZXN0IG1vZGVsbGVkIGJ5IGEgMm5kLSBvciAzcmQtb3JkZXIgcG9seW5vbWlhbCBhbmQgbWVldCB0aGUgbnVtZXJpY2FsIGluY2x1c2lvbiBjcml0ZXJpYS4gVGhlIGhvcml6b250YWwgc29saWQgb3JhbmdlIGxpbmUgc2hvd3MgdGhlIHN0YW5kYXJkIG1ldGFib2xpYyByYXRlIChTTVIpLCB0aGUgaG9yaXpvbnRhbCBzb2xpZCBwaW5rIGxpbmUgc2hvd3MgdGhlbG93ZXN0TU8yIChhcyBkZWZpbmVkIGJ5ICBDbGFpcmVhdXggYW5kIENoYWJvdCAoMjAxNikpLCB0aGUgc29saWQvZGFzaGVkIGJsdWUvZ3JlZW4gc2xvcGUgbGluZSBzaG93cyB0aGUgTzIgcmVndWxhdGlvbiBmYWlsdXJlIHJlZ3Jlc3Npb24gKGJhc2VkIG9uIHRoZSBydWxlLWJhc2VkIGxpbmVhciByZWdyZXNzaW9uIG1ldGhvZCBvZiBDbGFpcmVhdXggYW5kIENoYWJvdCAoMjAxNik7IHdoZXJlIHRoZSBjb2xvdXIgYW5kIGxpbmUgdHlwZSBpbmRpY2F0ZSB0aGUgdHlwZSBvZiByZWdyZXNzaW9uIGZpdHRlZCwgdGhyb3VnaCBvcmdpbiBvciBub3QpLCBhbmQgdGhlIHNvbGlkIHZlcnRpY2FsIGJsdWUvZ3JlZW4gbGluZSBzaG93cyB0aGUgTzJjcml0IGVzdGltYXRlIChpbnRlcnNlY3Rpb24gb2YgTzIgZmFpbHVyZSByZWdyZXNzaW9uIGFuZCBTTVIpLg0KDQpQdWxsaW5nIG1vZGVsIG1ldGhvZCBhbmQgbGV0aGFsIHBvaW50cw0KDQpgYGB7cn0NCmlkcyA8LSBwY3JpdF9tb2RlbF9tZXRhICU+JSANCiAgZHBseXI6OmRpc3RpbmN0KGlkKSAlPiUgDQogIGRwbHlyOjpwdWxsKCkNCg0KcGNyaXRfbWVhbl9wbG90IDwtIGxpc3QoKQ0KDQpmb3IgKGlkX2kgaW4gaWRzKSB7DQogIGJlc3RfbW9kX3R5cGUgPC0gYmVzdF9tb2QgJT4lDQogICAgZHBseXI6OmZpbHRlcihpZCA9PSBpZF9pKSAlPiUgDQogICAgcHVsbChtb2RlbF90eXBlKQ0KICBtb2QgPC0gcGNyaXRfbW9kZWxzW1tpZF9pXV0NCiAgZGF0YSA8LSBtb2Qkb3JpZ0RhdGENCiAgbWluX2xlYXRoYWwgPC0gbWluKG1vZCRsZXRoYWxQb2ludHMpDQogIG1ldGhvZCA8LSBtb2QkTWV0aG9kDQogIHBjcml0IDwtIG1vZCRvMmNyaXQNCiAgZGF0YV9zbG9wZSA8LSBkYXRhICU+JQ0KICAgIGRwbHlyOjptdXRhdGUobl9yb3cgPSAxOm5yb3coLiksDQogICAgICAgICAgICAgICAgICBsZWF0aGFsID0gaWZfZWxzZShuX3JvdyA+PSBtaW5fbGVhdGhhbCwgIm5vbnJlZ3VsYXRpb24iLCAicmVndWxhdGlvbiIpLA0KICAgICAgICAgICAgICAgICAgbWV0aG9kID0gbWV0aG9kLA0KICAgICAgICAgICAgICAgICAgcGNyaXQgPSBwY3JpdCwNCiAgICAgICAgICAgICAgICAgIGJlc3RfbW9kX3R5cGUgPSBiZXN0X21vZF90eXBlDQogICAgKQ0KICBwY3JpdF9tZWFuX3Bsb3RbW2lkX2ldXSA8LSBkYXRhX3Nsb3BlDQp9DQoNCnBjcml0X21lYW5fcGxvdF9kZiA8LSBiaW5kX3Jvd3MocGNyaXRfbWVhbl9wbG90KQ0KYGBgDQoNCg0KIyMjIEZpZ3VyZSBTOQ0KDQpNYWtpbmcgYSBPMmNyaXQgcGxvdCBmb3IgZWFjaCBvZiB0aGUgZWlnaHQgZmlzaCB0aGF0IHBhc3QgdmlzdWFsIGFuZCAgbnVtZXJpY2FsIGFzc2Vzc21lbnQgb24gdGhlIHNhbWUgYXhpcy4gICANCg0KYGBge3J9DQpwY3JpdF9zdW1tYXJ5IDwtIHBjcml0X21lYW5fcGxvdF9kZiAlPiUNCiAgZHBseXI6OmZpbHRlcihpZCAlaW4lIHNoYXJlZF9lbGVtZW50cykgJT4lIA0KICBncm91cF9ieShpZCkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBTTVIgPSBmaXJzdChTTVIpLA0KICAgIHBjcml0ID0gZmlyc3QocGNyaXQpLA0KICAgIG1heF9ETyA9IG1heChETywgbmEucm0gPSBUUlVFKSwNCiAgICBtZXRob2QgPSBmaXJzdChtZXRob2QpLA0KICAgIC5ncm91cHMgPSAiZHJvcCINCiAgKQ0KDQpzbW9vdGhfc2VnbWVudHMgPC0gbWFwX2Rmcih1bmlxdWUocGNyaXRfc3VtbWFyeSRpZCksIGZ1bmN0aW9uKGN1cl9pZCkgew0KICANCiAgc3VtX2luZm8gPC0gcGNyaXRfc3VtbWFyeSAlPiUgZmlsdGVyKGlkID09IGN1cl9pZCkNCiAgU01SX3ZhbCA8LSBzdW1faW5mbyRTTVINCiAgbWV0aG9kX3ZhbCA8LSBzdW1faW5mbyRtZXRob2QNCiAgDQogIGRmIDwtIHBjcml0X21lYW5fcGxvdF9kZiAlPiUNCiAgICBmaWx0ZXIoaWQgPT0gY3VyX2lkLCBsZWF0aGFsID09ICJub25yZWd1bGF0aW9uIikNCiAgDQogIGlmKG5yb3coZGYpIDwgMikgcmV0dXJuKE5VTEwpDQogIA0KICAjIEZpdCB0aGUgYXBwcm9wcmlhdGUgbW9kZWwNCiAgaWYobWV0aG9kX3ZhbCA9PSAidGhyb3VnaF9vcmlnaW4iKSB7DQogICAgbW9kZWwgPC0gbG0oTU8yIH4gRE8gKyAwLCBkYXRhID0gZGYpDQogIH0gZWxzZSB7DQogICAgbW9kZWwgPC0gbG0oTU8yIH4gRE8sIGRhdGEgPSBkZikNCiAgfQ0KICANCiAgY29lZnMgPC0gY29lZihtb2RlbCkNCiAgDQogIGlmKG1ldGhvZF92YWwgPT0gInRocm91Z2hfb3JpZ2luIikgew0KICAgIHNsb3BlIDwtIGNvZWZzWzFdDQogICAgRE9fc3RhcnQgPC0gMA0KICAgIERPX3N0b3AgPC0gU01SX3ZhbCAvIHNsb3BlDQogIH0gZWxzZSB7DQogICAgaW50ZXJjZXB0IDwtIGNvZWZzWzFdDQogICAgc2xvcGUgPC0gY29lZnNbMl0NCiAgICAjIEZvciBMU19yZWcsIHN0YXJ0IGF0IDAgaWYgcHJlZGljdGlvbiBpcyBhbHJlYWR5IHBvc2l0aXZlLA0KICAgICMgb3IgYXQgdGhlIERPIHdoZXJlIHByZWRpY3RlZCBNTzIgYmVjb21lcyAwIGlmIG5vdC4NCiAgICBET19zdGFydCA8LSBpZihpbnRlcmNlcHQgPCAwKSAtaW50ZXJjZXB0IC8gc2xvcGUgZWxzZSAwDQogICAgRE9fc3RvcCA8LSAoU01SX3ZhbCAtIGludGVyY2VwdCkgLyBzbG9wZQ0KICB9DQogIA0KICAjIElNUE9SVEFOVDogRG8gbm90IGJvdW5kIERPX3N0b3AgYnkgbWF4KGRmJERPKSBpZiB5b3Ugd2FudCB0byBleHRyYXBvbGF0ZQ0KICAjIERPX3N0b3AgPC0gbWluKERPX3N0b3AsIG1heChkZiRETywgbmEucm0gPSBUUlVFKSkgICMgPC0tIFJlbW92ZSBvciBjb21tZW50IG91dCB0aGlzIGxpbmUNCiAgDQogICMgQ3JlYXRlIGEgc2VxdWVuY2UgZnJvbSBET19zdGFydCB0byBET19zdG9wDQogIERPX3NlcSA8LSBzZXEoRE9fc3RhcnQsIERPX3N0b3AsIGxlbmd0aC5vdXQgPSAxMDApDQogIA0KICAjIENhbGN1bGF0ZSB0aGUgcHJlZGljdGVkIE1PMiB2YWx1ZXMgZm9yIHRoaXMgc2VxdWVuY2UNCiAgTU8yX3ByZWQgPC0gaWYobWV0aG9kX3ZhbCA9PSAidGhyb3VnaF9vcmlnaW4iKSB7DQogICAgc2xvcGUgKiBET19zZXENCiAgfSBlbHNlIHsNCiAgICBpbnRlcmNlcHQgKyBzbG9wZSAqIERPX3NlcQ0KICB9DQogIA0KICB0aWJibGUoDQogICAgaWQgPSBjdXJfaWQsDQogICAgRE8gPSBET19zZXEsDQogICAgTU8yX3ByZWQgPSBNTzJfcHJlZA0KICApIA0KICB9KQ0KDQpGaWdfczkgPC0gZ2dwbG90KCkgKw0KICBnZW9tX3BvaW50KGRhdGEgPSBwY3JpdF9tZWFuX3Bsb3RfZGYgJT4lDQogICAgICAgICAgICAgICBkcGx5cjo6ZmlsdGVyKGlkICVpbiUgc2hhcmVkX2VsZW1lbnRzKSwgDQogICAgICAgICAgICAgYWVzKHggPSBETywgeSA9IE1PMiwgY29sb3VyID0gaWQsIGFscGhhID0gbGVhdGhhbCkpICsNCiAgc2NhbGVfYWxwaGFfbWFudWFsKHZhbHVlcyA9IGMoInJlZ3VsYXRpb24iID0gMC4yLCAibm9ucmVndWxhdGlvbiIgPSAwLjgpKSArDQogIGd1aWRlcyhhbHBoYSA9ICJub25lIikgKw0KICBnZW9tX2xpbmUoZGF0YSA9IHNtb290aF9zZWdtZW50cywNCiAgICAgICAgICAgIGFlcyh4ID0gRE8sIHkgPSBNTzJfcHJlZCwgY29sb3VyID0gaWQpLCBsaW5ld2lkdGggPSAxLjIpICsNCiAgZ2VvbV9zZWdtZW50KGRhdGEgPSBwY3JpdF9zdW1tYXJ5LA0KICAgICAgICAgICAgIGFlcyh4ID0gcGNyaXQsIHhlbmQgPSBtYXhfRE8sIHkgPSBTTVIsIHllbmQgPSBTTVIpKSArDQogIGdlb21fc2VnbWVudChkYXRhID0gcGNyaXRfc3VtbWFyeSwNCiAgICAgICAgICAgICAgIGFlcyh4ID0gcGNyaXQsIHhlbmQgPSBwY3JpdCwgeSA9IDAsIHllbmQgPSBTTVIpKSArDQogIHNjYWxlX2NvbG91cl92aXJpZGlzX2Qob3B0aW9uID0gInBsYXNtYSIpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgbGFicygNCiAgICB5ID0gZXhwcmVzc2lvbigibWcgTyJbMl1+ImgiXi0xKSwNCiAgICB4ID0gIkRpc3NvbHZlZCBveHlnZW4gKERPOyAlIHNhdHVyYXRpb24pIg0KICApICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpDQoNCkZpZ19zOQ0KYGBgDQoNCg0KKipGaWd1cmUgUzkqKjogT3h5Z2VuIGNvbnN1bXB0aW9uIHJhdGUgKOG5gE/igoI7IG1n4oG7wrkgT+KCgiBo4oG7wrkpIGFuZCBhbWJpZW50IGRpc3NvbHZlZCBveHlnZW4gKERPOyAlIHNhdHVyYXRpb24pIHBsb3R0ZWQgZm9yIGVhY2ggZmlzaCB0aGF0IHBhc3NlZCBib3RoIHBhc3QgdmlzdWFsIGFuZCAgbnVtZXJpY2FsIGFzc2Vzc21lbnQgZm9yIE88c3ViPjJjcml0PC9zdWI+LiBUaGUgaG9yaXpvbnRhbCBkYXNoZWQgbGluZXMgc2hvdyBTTVIsIHRoZSBzb2xpZCBzbG9wZWQgbGluZXMgcmVwcmVzZW50IHRoZSBsaW5lYXIgYmVzdCBmaXQgZm9yIOG5gE8gdmFsdWVzIGJlbG93IHJlZ3VsYXRvcnkgZmFpbHVyZS4gVGhlIHZlcnRpY2FsIHNvaWxkIGxpbmVzIHJlcHJlc2VudCBPPHN1Yj4yY3JpdDwvc3ViPiAodGhlIGludGVyc2VjdGlvbiBvZiB0aGUgbGluZWFyIGJlc3QgZml0IGZvciDhuYBPIHZhbHVlcyBiZWxvdyByZWd1bGF0b3J5IGZhaWx1cmUgYW5kIFNNUikuDQoNCg0KDQojIyMgRmlndXJlIDINCg0KTGV0J3MgbWFrZSBzb21lIGV4YW1wbGUgcGxvdHMgZm9yIGVhY2ggbWFqb3IgdHlwZXMgb2YgTzItTU8yIHJlbGF0aW9uc2hpcHMgKGkuZS4gMF50aF4tLCAxXnN0Xi0sIGFuZCAyXm5kXi8zXnJkXi0gb3JkZXIgcG9seW5vbWlhbCkuICAgDQoNCkZpcnN0IGFuIGV4YW1wbGUgb2YgYSAwdGgtb3JkZXIgcG9seW5vbWlhbCBmaXQgKGNfOV8yNG5vdl80KS4gICANCg0KYGBge3J9DQpmaWdfMmEgPC0gYmF5ZXNfcmVnX21vZHNfcHJlZGljdGlvbnMgJT4lDQogIGRwbHlyOjpmaWx0ZXIoaWQgPT0gImNfOV8yNG5vdl80IiwgbW9kZWxfdHlwZSA9PSAibG1fMCIpICU+JSANCiAgZ2dwbG90KCkgKw0KICBnZW9tX3BvaW50KGFlcyh4ID0gRE8sIHkgPSBNTzIpLCBjb2xvdXIgPSAiYmxhY2siLCBzaXplID0gMywgYWxwaGEgPSAwLjUpICsNCiAgZ2VvbV9zZWdtZW50KA0KICAgIGFlcyh4ID0gMCwgeGVuZCA9IDEwMCwgeSA9IDAsIHllbmQgPSBTTVJbMV0pLCAjIFNNUg0KICAgIGxpbmV0eXBlID0gImRhc2hlZCIsIHNpemUgPSAxLCBjb2xvdXIgPSAiIzBGN0FBRiIpICsNCiAgZ2VvbV9zZWdtZW50KA0KICAgIGFlcyh4ID0gMCwgeGVuZCA9IDEwMCwgeSA9IFNNUlsxXSwgeWVuZCA9IFNNUlsxXSksICMgY29uZm9ybQ0KICAgIGxpbmV0eXBlID0gImRhc2hlZCIsIHNpemUgPSAxLCBjb2xvdXIgPSAiI0ZGQTUwMCIpICsNCiAgdGhlbWVfZmV3KCkgKw0KICAgIGxhYnMoDQogICAgeSA9IGV4cHJlc3Npb24oIm1nIE8iWzJdfiJoIl4tMSksDQogICAgeCA9IE5VTEwNCiAgKSArDQogIHRoZW1lKA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCkNCiAgKQ0KYGBgDQoNCg0KU2Vjb25kIGFuIGV4YW1wbGUgb2YgYSAxc3Qtb3JkZXIgcG9seW5vbWlhbCBiZXN0IGZpdCAoZF85XzI1bm92XzMpLiAgDQoNCmBgYHtyfQ0KZmlnXzJiIDwtIGJheWVzX3JlZ19tb2RzX3ByZWRpY3Rpb25zICU+JQ0KICBkcGx5cjo6ZmlsdGVyKGlkID09ICJkXzlfMjVub3ZfMyIsIG1vZGVsX3R5cGUgPT0gImxtXzEiKSAlPiUgDQogIGdncGxvdCgpICsNCiAgZ2VvbV9wb2ludChhZXMoeCA9IERPLCB5ID0gTU8yKSwgY29sb3VyID0gImJsYWNrIiwgc2l6ZSA9IDMsIGFscGhhID0gMC41KSArDQogICMgZ2VvbV9saW5lKGFlcyh4ID0gRE8sIHkgPSBwcmVkaWN0ZWQgKiBtYXNzKSwgc2l6ZSA9IDIsIGNvbG91ciA9ICJibHVlIikgKw0KICBnZW9tX3NlZ21lbnQoDQogICAgYWVzKHggPSAwLCB4ZW5kID0gMTAwLCB5ID0gMCwgeWVuZCA9IFNNUlsxXSksICMgU01SDQogICAgbGluZXR5cGUgPSAiZGFzaGVkIiwgc2l6ZSA9IDEsIGNvbG91ciA9ICIjMEY3QUFGIikgKw0KICBnZW9tX3NlZ21lbnQoDQogICAgYWVzKHggPSAwLCB4ZW5kID0gMTAwLCB5ID0gU01SWzFdLCB5ZW5kID0gU01SWzFdKSwgIyBjb25mb3JtDQogICAgbGluZXR5cGUgPSAiZGFzaGVkIiwgc2l6ZSA9IDEsIGNvbG91ciA9ICIjRkZBNTAwIikgKw0KICB0aGVtZV9mZXcoKSArDQogIGxhYnMoDQogICAgeSA9IGV4cHJlc3Npb24oIm1nIE8iWzJdfiJoIl4tMSksDQogICAgeCA9IE5VTEwNCiAgKSArDQogIHRoZW1lKA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKQ0KICApDQoNCmBgYA0KDQoNCkxhc3QgYW4gZXhhbXBsZSBvZiBhIGZpc2ggYmVzdCBmaXQgd2l0aCBhIGhpZ2hlciBvcmRlciBwb2x5bm9taWFsICgybmQtb3JkZXIpLg0KDQpgYGB7cn0NCiMgRGVmaW5lIHRoZSBleGFtcGxlIElEDQpwY3JpdF9leGFtcGxlIDwtICJiXzBfMjRub3ZfMSINCg0KIyAxLiBQcmVwYXJlIHN1bW1hcnkgZGF0YSBmb3IgdGhlIHNlbGVjdGVkIElEDQpwY3JpdF9zdW1tYXJ5X2V4YW1wbGUgPC0gcGNyaXRfbWVhbl9wbG90X2RmICU+JQ0KICBmaWx0ZXIoaWQgPT0gcGNyaXRfZXhhbXBsZSkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBTTVIgPSBmaXJzdChTTVIpLA0KICAgIHBjcml0ID0gZmlyc3QocGNyaXQpLA0KICAgIG1heF9ETyA9IG1heChETywgbmEucm0gPSBUUlVFKSwNCiAgICBtZXRob2QgPSBmaXJzdChtZXRob2QpLA0KICAgIC5ncm91cHMgPSAiZHJvcCINCiAgKQ0KDQojIDIuIFN1YnNldCB0aGUgb3JpZ2luYWwgbm9ucmVndWxhdGlvbiBkYXRhDQpkZiA8LSBwY3JpdF9tZWFuX3Bsb3RfZGYgJT4lDQogIGZpbHRlcihpZCA9PSBwY3JpdF9leGFtcGxlLCBsZWF0aGFsID09ICJub25yZWd1bGF0aW9uIikNCg0KIyAzLiBGaXQgbW9kZWwgYW5kIGdlbmVyYXRlIHByZWRpY3Rpb25zDQppZiAobnJvdyhkZikgPj0gMikgew0KICBTTVJfdmFsIDwtIHBjcml0X3N1bW1hcnlfZXhhbXBsZSRTTVINCiAgbWV0aG9kX3ZhbCA8LSBwY3JpdF9zdW1tYXJ5X2V4YW1wbGUkbWV0aG9kDQogIA0KICBpZiAobWV0aG9kX3ZhbCA9PSAidGhyb3VnaF9vcmlnaW4iKSB7DQogICAgbW9kZWwgPC0gbG0oTU8yIH4gRE8gKyAwLCBkYXRhID0gZGYpDQogICAgc2xvcGUgPC0gY29lZihtb2RlbClbMV0NCiAgICBET19zdGFydCA8LSAwDQogICAgRE9fc3RvcCA8LSBTTVJfdmFsIC8gc2xvcGUNCiAgICBNTzJfcHJlZCA8LSBzbG9wZSAqIHNlcShET19zdGFydCwgRE9fc3RvcCwgbGVuZ3RoLm91dCA9IDEwMCkNCiAgfSBlbHNlIHsNCiAgICBtb2RlbCA8LSBsbShNTzIgfiBETywgZGF0YSA9IGRmKQ0KICAgIGludGVyY2VwdCA8LSBjb2VmKG1vZGVsKVsxXQ0KICAgIHNsb3BlIDwtIGNvZWYobW9kZWwpWzJdDQogICAgRE9fc3RhcnQgPC0gaWYgKGludGVyY2VwdCA8IDApIC1pbnRlcmNlcHQgLyBzbG9wZSBlbHNlIDANCiAgICBET19zdG9wIDwtIChTTVJfdmFsIC0gaW50ZXJjZXB0KSAvIHNsb3BlDQogICAgRE9fc2VxIDwtIHNlcShET19zdGFydCwgRE9fc3RvcCwgbGVuZ3RoLm91dCA9IDEwMCkNCiAgICBNTzJfcHJlZCA8LSBpbnRlcmNlcHQgKyBzbG9wZSAqIERPX3NlcQ0KICB9DQogIA0KICBET19zZXEgPC0gc2VxKERPX3N0YXJ0LCBET19zdG9wLCBsZW5ndGgub3V0ID0gMTAwKQ0KICANCiAgc21vb3RoX3NlZ21lbnQgPC0gdGliYmxlKA0KICAgIGlkID0gcGNyaXRfZXhhbXBsZSwNCiAgICBETyA9IERPX3NlcSwNCiAgICBNTzJfcHJlZCA9IE1PMl9wcmVkDQogICkNCn0NCg0KIyA0LiBQbG90IHRoZSBmaWd1cmUNCmZpZ18yYyA8LSBnZ3Bsb3QoKSArDQogIGdlb21fcG9pbnQoDQogICAgZGF0YSA9IHBjcml0X21lYW5fcGxvdF9kZiAlPiUgZmlsdGVyKGlkID09IHBjcml0X2V4YW1wbGUpLA0KICAgIGFlcyh4ID0gRE8sIHkgPSBNTzIsIGNvbG91ciA9IGxlYXRoYWwpLCBzaXplID0gMywgYWxwaGEgPSAwLjUNCiAgKSArDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygicmVndWxhdGlvbiIgPSAiYmxhY2siLCAibm9ucmVndWxhdGlvbiIgPSAiI2MzMDAxMCIpKSArDQogIA0KICAjIGdlb21fc21vb3RoKGRhdGEgPSBwY3JpdF9tZWFuX3Bsb3RfZGYgJT4lIGZpbHRlcihpZCA9PSBwY3JpdF9leGFtcGxlKSwNCiAgIyAgICAgICAgICAgICBhZXMoeCA9IERPLCB5ID0gTU8yKSwgbWV0aG9kID0gImxtIiwgZm9ybXVsYSA9IHkgfiBwb2x5KHgsIDMpLCBzZSA9IEZBTFNFLCBhbHBoYSA9IDAuOCwgc2l6ZSA9IDIsIGZ1bGxyYW5nZSA9IFRSVUUpICsNCiAgDQogIGdlb21fbGluZSgNCiAgICBkYXRhID0gc21vb3RoX3NlZ21lbnQsDQogICAgYWVzKHggPSBETywgeSA9IE1PMl9wcmVkKSwgc2l6ZSA9IDIsIGNvbG91ciA9ICIjYzMwMDEwIiAjZmFpbHVyZSAgc2xvcGUNCiAgKSArDQogIA0KICANCiAgZ2VvbV9zZWdtZW50KA0KICAgIGRhdGEgPSBwY3JpdF9zdW1tYXJ5X2V4YW1wbGUsDQogICAgYWVzKHggPSAwLCB4ZW5kID0gbWF4X0RPLCB5ID0gU01SLCB5ZW5kID0gU01SKSwgI1NNUg0KICAgIGNvbG91ciA9ICIjRkZBNTAwIiwgbGluZXR5cGUgPSAiZGFzaGVkIiwgc2l6ZSA9IDEpICsNCiAgDQogIGdlb21fc2VnbWVudCgNCiAgICBkYXRhID0gcGNyaXRfc3VtbWFyeV9leGFtcGxlLA0KICAgIGFlcyh4ID0gMCwgeGVuZCA9IG1heF9ETywgeSA9IDAsIHllbmQgPSBTTVIpLCAjY29uZnJvbQ0KICAgIGxpbmV0eXBlID0gImRhc2hlZCIsIHNpemUgPSAxLCBjb2xvdXIgPSAiIzBGN0FBRiIpICsNCiAgDQogIGdlb21fc2VnbWVudCgNCiAgICBkYXRhID0gcGNyaXRfc3VtbWFyeV9leGFtcGxlLA0KICAgIGFlcyh4ID0gcGNyaXQsIHhlbmQgPSBwY3JpdCwgeSA9IDAsIHllbmQgPSBTTVIpLCBjb2xvdXIgPSAiZGFya2dyZWVuIiwgc2l6ZSA9IDIgI1Bjcml0DQogICkgKw0KICANCiAgI2Nvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLCAwLjE2KSkgKw0KICB0aGVtZV9mZXcoKSArDQogICBsYWJzKA0KICAgIHkgPSBleHByZXNzaW9uKCJtZyBPIlsyXX4iaCJeLTEpLA0KICAgIHggPSAiRGlzc29sdmVkIG94eWdlbiAoRE87ICUgc2F0dXJhdGlvbikiDQogICkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQoNCmBgYA0KDQoNCkxldCdzIGNvbWJpbmVkIHRoZW0gaW4gb25lIHBsb3QNCg0KYGBge3IsIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD01fQ0KZmlnXzJfYmluZCA8LSBncmlkLmFycmFuZ2UoZmlnXzJhLCBmaWdfMmIsIGZpZ18yYywgbmNvbCA9IDEpICNiaW5kIHBsb3QNCmBgYA0KDQoqKkZpZ3VyZSAyKio6IEZpZ3VyZSAyLiBSZXByZXNlbnRhdGl2ZSBleGFtcGxlcyBvZiBmaXNoIHRoYXQgd2VyZSBiZXN0IG1vZGVsbGVkIGJ5IGEgMHRoLW9yZGVyIHBvbHlub21pYWwgKEEpLCAxc3Qtb3JkZXIgcG9seW5vbWlhbCAoQiksIGFuZCAybmQtb3JkZXIgcG9seW5vbWlhbCAoQykuIFRoZSBvcmFuZ2UgZGFzaGVkIGxpbmUgc2hvd3MgdGhlIFNNUiwgd2hpbGUgdGhlIGJsdWUgZGFzaGVkIGxpbmUgc2hvd3MgdGhlIHRoZW9yZXRpY2FsIG94eWNvbmZyb21pbmcgcmVncmVzc2lvbi4gRm9yIHBsb3QgKEMpLCB0aGUgcmVkIHNsb3BlZCBsaW5lIHNob3dzIHRoZSBPMiByZWd1bGF0aW9uIGZhaWx1cmUgcmVncmVzc2lvbiAoYmFzZWQgb24gdGhlIHJ1bGUtYmFzZWQgbGluZWFyIHJlZ3Jlc3Npb24gbWV0aG9kIG9mIENsYWlyZWF1eCBhbmQgQ2hhYm90LCAyMDE2KSwgYW5kIHRoZSBzb2xpZCBob3Jpem9udGFsIGdyZWVuIGxpbmUgc2hvd3MgdGhlIE8yY3JpdCBlc3RpbWF0ZSAoaW50ZXJzZWN0aW9uIG9mIE8yIGZhaWx1cmUgcmVncmVzc2lvbiBhbmQgU01SKS4gIA0KDQpgYGB7cn0NCiMgZ2dzYXZlKGZpbGVuYW1lID0gcGFzdGUwKG91dHB1dF9maWdfd2QsICIuL21zX2ZpZ3VyZXMuL2ZpZ3VyZS0yLnBkZiIpLA0KIyAgICAgICAgcGxvdCA9IGZpZ18yX2JpbmQsDQojICAgICAgICB3aWR0aCA9IDIxMCwNCiMgICAgICAgIGhlaWdodCA9IDI5NywNCiMgICAgICAgIHVuaXRzID0gIm1tIikNCmBgYA0KDQoNCiMgQ29tYXByaW5nIHRvIHBhc3QgZGF0YQ0KDQpIZXJlLCB3ZSBoYXZlIHJlY3JlYXRlZCBhIHNpbWlsYXIgcGxvdCB0byB0aGF0IHByZXNlbnRlZCBpbiBVcmJpbmEsIEdsb3ZlciwgYW5kIEZvcnN0ZXIgKDIwMTIpXlsxXV4gYW5kIGhhdmUgZXh0cmFjdGVkIHRoZSBtZWFuIGxldmVsIGRhdGEgZnJvbSBGaWd1cmUgMWEgdXNpbmcgdGhlIG1ldGFEaWdpdGlzZSBwYWNrYWdlIGluIFJeWzNdXi4gVGhpcyBkYXRhIGlzIGNhbGxlZCB1cmJpbmFfZXRfYWxfMjAxMi4gVGhpcyBhbGxvd3MgdXMgdG8gY29tcGFyZSB0aGUgZGlmZmVyZW5jZXMgaW4gTW8yIGFuZCB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gTW8yIGFuZCBPPHN1Yj4yPC9zdWI+Lg0KDQpGaXJzdCBtYWtpbmcgYSBiaW5uZWQgZGF0YSBmcmFtZSB0byBtYXRjaCBVcmJpbmEsIEdsb3ZlciwgYW5kIEZvcnN0ZXIgKDIwMTIpIGFzIGNsb3NlbHkgYXMgcG9zc2libGUuDQoNCmBgYHtyfQ0KbWluX28yX2twYSA8LSBtaW4oc2xvcGVfdGlkeSRvMl9rcGEsIG5hLnJtID0gVFJVRSkNCm1heF9vMl9rcGEgPC0gbWF4KHNsb3BlX3RpZHkkbzJfa3BhLCBuYS5ybSA9IFRSVUUpDQoNCnRpbWVfYmluX2RmIDwtIHNsb3BlX3RpZHkgJT4lDQogIG11dGF0ZShvMl9ncm91cCA9IGN1dChvMl9rcGEsIA0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gc2VxKG1pbl9vMl9rcGEsIG1heF9vMl9rcGEsIGxlbmd0aC5vdXQgPSAxMyksICMgMTEgaW50ZXJ2YWxzLCBzbyAxMiBicmVha3BvaW50cw0KICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gcGFzdGUwKCJHcm91cCAiLCAxOjEyKSwgDQogICAgICAgICAgICAgICAgICAgICAgICBpbmNsdWRlLmxvd2VzdCA9IFRSVUUpKSAlPiUgDQogIGRwbHlyOjpncm91cF9ieShvMl9ncm91cCkgJT4lIA0KICBkcGx5cjo6cmVmcmFtZShtZWFuX01PMl9nID0gbWVhbihNTzJfZykqMzEuMjUsDQogICAgICAgICAgICAgICAgIG1lYW5fbzJfa3BhID0gbWVhbihvMl9rcGEpLA0KICAgICAgICAgICAgICAgICBuID0gbGVuZ3RoKE1PMl9nKSozMS4yNSwNCiAgICAgICAgICAgICAgICAgTU8yX2dfc2QgPSBzZChNTzJfZykqMzEuMjUsDQogICAgICAgICAgICAgICAgIG8yX2twYV9zZCA9IHNkKG8yX2twYSkpDQpgYGANCg0KIyMgRmlndXJlIDMNCg0KTm93IHRoZSBwbG90IHdpdGggb3VyIG1lYW4gZGF0YSBhbmQgdGhlIG1lYW4gZGF0YSBmcm9tIFVyYmluYSwgR2xvdmVyLCBhbmQgRm9yc3RlciAoMjAxMileWzFdXiAgIA0KDQpgYGB7cn0NCm4gPC0gc2xvcGVfdGlkeSAlPiUgDQogIGRwbHlyOjpkaXN0aW5jdChpZCkgJT4lIA0KICBucm93KC4pDQoNCiMgRXhpc3RpbmcgcGxvdA0KZmlnMyA8LSB0aW1lX2Jpbl9kZiAlPiUgDQogIGdncGxvdCgpICsNCiAgZ2VvbV9wb2ludChkYXRhID0gc2xvcGVfdGlkeSwgDQogICAgICAgICAgICAgYWVzKHkgPSBNTzJfZyAqIDMxLjI1LCB4ID0gbzJfa3BhKSwgDQogICAgICAgICAgICAgc2l6ZSA9IDIsIGNvbG9yID0gImdyZXkiLCBhbHBoYSA9IDAuMykgKyAgDQogIGdlb21fcG9pbnQoZGF0YSA9IHRpbWVfYmluX2RmLCANCiAgICAgICAgICAgICBhZXMoeSA9IG1lYW5fTU8yX2csIHggPSBtZWFuX28yX2twYSksDQogICAgICAgICAgICAgc2l6ZSA9IDMsIGNvbG91ciA9ICIjMEU0QzkyIiwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKw0KICBnZW9tX2Vycm9yYmFyKGRhdGEgPSB0aW1lX2Jpbl9kZiwNCiAgICAgICAgICAgICAgICBhZXMoeSA9IG1lYW5fTU8yX2csIHggPSBtZWFuX28yX2twYSwNCiAgICAgICAgICAgICAgICAgICAgeW1pbiA9IG1lYW5fTU8yX2cgLSBNTzJfZ19zZCwgeW1heCA9IG1lYW5fTU8yX2cgKyBNTzJfZ19zZCksIA0KICAgICAgICAgICAgICAgIHdpZHRoID0gMC4xNSwgY29sb3VyID0gIiMwRTRDOTIiKSArDQogIGdlb21fZXJyb3JiYXJoKGRhdGEgPSB0aW1lX2Jpbl9kZiwgDQogICAgICAgICAgICAgICAgIGFlcyh5ID0gbWVhbl9NTzJfZywgeCA9IG1lYW5fbzJfa3BhLA0KICAgICAgICAgICAgICAgICAgICAgeG1pbiA9IG1lYW5fbzJfa3BhIC0gbzJfa3BhX3NkLCB4bWF4ID0gbWVhbl9vMl9rcGEgKyBvMl9rcGFfc2QpLCANCiAgICAgICAgICAgICAgICAgaGVpZ2h0ID0gMC40LCBjb2xvdXIgPSAiIzBFNEM5MiIpICsNCiAgZ2VvbV9wb2ludChkYXRhID0gdXJiaW5hX2V0X2FsXzIwMTIsIA0KICAgICAgICAgICAgIGFlcyh4ID0gbzJfbWVhbiwgeSA9IG1vMl9tZWFuKSwgDQogICAgICAgICAgICAgc2l6ZSA9IDMsIHNoYXBlID0gMSwgZmlsbCA9ICIjRDIxRjNDIiwgY29sb3IgPSAiI0QyMUYzQyIsIHN0cm9rZSA9IDEpICsNCiAgZ2VvbV9lcnJvcmJhcihkYXRhID0gdXJiaW5hX2V0X2FsXzIwMTIsIA0KICAgICAgICAgICAgICAgIGFlcyh4ID0gbzJfbWVhbiwgeW1pbiA9IG1vMl9tZWFuIC0gbW8yX3NkLCB5bWF4ID0gbW8yX21lYW4gKyBtbzJfc2QpLCANCiAgICAgICAgICAgICAgICB3aWR0aCA9IDAuMiwgY29sb3VyID0gIiNEMjFGM0MiKSArDQogIGdlb21fZXJyb3JiYXJoKGRhdGEgPSB1cmJpbmFfZXRfYWxfMjAxMiwgDQogICAgICAgICAgICAgICAgIGFlcyh5ID0gbW8yX21lYW4sIHhtaW4gPSBvMl9tZWFuIC0gbzJfc2QsIHhtYXggPSBvMl9tZWFuICsgbzJfc2QpLCANCiAgICAgICAgICAgICAgICAgaGVpZ2h0ID0gMC40LCBjb2xvdXIgPSAiI0QyMUYzQyIpICsNCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gMCwgDQogICAgICAgICAgIHkgPSAxNiwgDQogICAgICAgICAgIGxhYmVsID0gYnF1b3RlKGF0b3AoIkN1cnJlbnQgZGF0YSAoYmx1ZSksICIgKiBpdGFsaWMobikgKiAiID0gIiAqIC4obiksDQogICAgICAgICAgICAgICAgICAgICAgICAiVXJiaW5hIGRhdGEgKHJlZCksICIgKiBpdGFsaWMobikgKiAiID0gNjciKSksICANCiAgICAgICAgIGhqdXN0ID0gMCwgdmp1c3QgPSAxLCBzaXplID0gNCkgKw0KICB0aGVtZSgNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiYmxhY2siLCBmaWxsID0gTkEsIGxpbmV3aWR0aCA9IDEpLA0KICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIsIGNvbG91ciA9IE5BKSwNCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIsIGNvbG91ciA9IE5BKQ0KICApICsNCiAgbGFicygNCiAgc3VidGl0bGUgPSBOVUxMLA0KICB4ID0gZXhwcmVzc2lvbigiUE8iWzJdfiIoa1BhKSIpLA0KICB5ID0gZXhwcmVzc2lvbigiTU8iWzJdfiIozrxtb2wgTyJbMl1+ImciXi0xfiJoIl4tMSkpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMTYpLCBicmVha3MgPSBzZXEoMCwgMTYsIGJ5ID0gMikpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMjIpLCBicmVha3MgPSBzZXEoMCwgMjIsIGJ5ID0gMikpICANCg0KZmlnMw0KYGBgDQoNCioqRmlndXJlIDM6KiogTWVhbiBhbmQgc3RhbmRhcmQgZXJyb3Igb2YgbWV0YWJvbGljIHJhdGUgKE1PPHN1Yj4yPC9zdWI+IM68bW9sIE88c3ViPjI8L3N1Yj4gZ14tMV4gaF4tMV4pIGFuZCBveHlnZW4gY29uY2VudHJhdGlvbiAoUE88c3ViPjI8L3N1Yj4ga1BhKSB1c2luZyAxMiBldmVubHkgc3BhY2VkIGJpbnMgb3ZlciB0aGUgTzxzdWI+Mjwvc3ViPiByYW5nZSBvZiBvYnNlcnZlZCBkYXRhIChibHVlIGZpbGxlZCBkb3RzKS4gQ29tcGFyZWQgYWdhaW5zdCB0aGUgbWVhbiBhbmQgc3RhbmRhcmQgZXJyb3IgcmVwb3J0ZWQgaW4gVXJiaW5hICgyMDEyKV5bMV1eIChyZWQgb3BlbiBkb3RzKS4gVGhlIGdyZXkgZG90cyBhcmUgdGhlIHJhdyBvYnNlcnZlZCBkYXRhIGZvcm0gdGhlIHByZXNlbnQgc3R1ZHkuDQoNCmBgYHtyfQ0KIyBnZ3NhdmUoZmlsZW5hbWUgPSBwYXN0ZTAob3V0cHV0X2ZpZ193ZCwgIi4vbXNfZmlndXJlcy4vZmlndXJlLTMucGRmIiksDQojICAgICAgICBwbG90ID0gZmlnMywNCiMgICAgICAgIHdpZHRoID0gMjEwLA0KIyAgICAgICAgaGVpZ2h0ID0gMjk3LzIsICAjIFNwZWNpZnkgdGhlIGhlaWdodCBvZiB0aGUgcGxvdA0KIyAgICAgICAgdW5pdHMgPSAibW0iKQ0KYGBgDQoNCjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT4NCg0KIyDwn5OaIFJlZmVyZW5jZXMNCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQpeWzFdXiBDbGFpcmVhdXgsIEcuIGFuZCBDaGFib3QsIEQuICgyMDE2KSBSZXNwb25zZXMgYnkgZmlzaGVzIHRvIGVudmlyb25tZW50YWwgaHlwb3hpYTogaW50ZWdyYXRpb24gdGhyb3VnaCBGcnkncyBjb25jZXB0IG9mIGFlcm9iaWMgbWV0YWJvbGljIHNjb3BlLiBKb3VybmFsIG9mIEZpc2ggQmlvbG9neSA8aHR0cHM6Ly9kb2kub3JnLzEwLjExMTEvamZiLjEyODMzPg0KDQpeWzJdXiBVcmJpbmEgTUEsIEdsb3ZlciBDTiwgYW5kIEZvcnN0ZXIgTUUsICgyMDEyKSBBIG5vdmVsIG94eWNvbmZvcm1pbmcgcmVzcG9uc2UgaW4gdGhlIGZyZXNod2F0ZXIgZmlzaCAqR2FsYXhpYXMgbWFjdWxhdHVzKi4gQ29tcGFyYXRpdmUgQmlvY2hlbWlzdHJ5IGFuZCBQaHlzaW9sb2d5IFBhcnQgQTogTW9sZWN1bGFyICYgSW50ZWdyYXRpdmUgUGh5c2lvbG9neS4gPGh0dHBzOi8vZG9pLm9yZy8xMC4xMDE2L2ouY2JwYS4yMDExLjExLjAxMT4NCg0KXlszXV4gUGljayBKTCwgTmFrYWdhd2EgUywgYW5kIE5vYmxlIERXQSAoMjAxOCkgUmVwcm9kdWNpYmxlLCBmbGV4aWJsZSBhbmQgaGlnaC10aHJvdWdocHV0IGRhdGEgZXh0cmFjdGlvbiBmcm9tIHByaW1hcnkgbGl0ZXJhdHVyZTogVGhlIG1ldGFEaWdpdGlzZSByIHBhY2thZ2UuIDxodHRwczovL2RvaS5vcmcvMTAuMTExMS8yMDQxLTIxMFguMTMxMTg+DQoNCjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT4NCg0KIyDwn5K7IFNlc3Npb24gaW5mb3JtYXRpb24NCg0KPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPg0KDQpgYGB7cn0NCmNpdGF0aW9uKCkNCmBgYA0KDQpIZXJlIGlzIGEgZGV0YWlsZWQgbGlzdCBvZiB0aGUgc2Vzc2lvbiBpbmZvcm1hdGlvbg0KDQpgYGB7cn0NCnNlc3Npb25pbmZvOjpzZXNzaW9uX2luZm8oKQ0KYGBgDQo=